项目中使用到了websocket长连接+点对点订阅,博客记录下。
长连接通常使用的是名称叫做STOMP的协议,具体跟服务器端的开发人员确认即可。
直接贴干货:
module build.gradle添加依赖:
compile 'com.github.NaikSoftware:StompProtocolAndroid:1.1.1'
compile 'org.java-websocket:Java-WebSocket:1.3.0'
工程的build.gradle添加:
maven { url "https://jitpack.io" }
长连接通常放在service里面
核心代码:
private void connect() {
mStompClient = Stomp.over(WebSocket.class, WS_URI);
mStompClient.connect();
mStompClient.lifecycle().subscribe(new Action1<LifecycleEvent>() {
@Override
public void call(LifecycleEvent lifecycleEvent) {
//关注lifecycleEvent的回调来决定是否重连
switch (lifecycleEvent.getType()) {
case OPENED:
mNeedConnect = false;
Log.d(TAG, "forlan debug stomp connection opened");
break;
case ERROR:
mNeedConnect = true;
Log.e(TAG, "forlan debug stomp connection error is ", lifecycleEvent.getException());
break;
case CLOSED:
mNeedConnect = true;
Log.d(TAG, "forlan debug stomp connection closed");
break;
}
}
});
registerStompTopic();
}
//创建长连接,服务器端没有心跳机制的情况下,启动timer来检查长连接是否断开,如果断开就执行重连
private void createStompClient() {
connect();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
Log.d(TAG, "forlan debug in timer ======================");
if (mNeedConnect && NetworkUtil.isNetworkConnected(getApplicationContext())) {
mStompClient = null;
connect();
Log.d(TAG, "forlan debug start connect WS_URI");
}
}
}, RECONNECT_TIME_INTERVAL, RECONNECT_TIME_INTERVAL);
}
//点对点订阅,根据用户名来推送消息
private void registerStompTopic() {
mStompClient.topic("/user/" + getUserAccount() + "/msg").subscribe(new Action1<StompMessage>() {
@Override
public void call(StompMessage stompMessage) {
Log.d(TAG, "forlan debug msg is " + stompMessage.getPayload());
}
});
}
点对点订阅的思想:启动长连接,针对特定的用户推送消息。捋明白后还是很简单明了。
感谢大神的文章,让我豁然开朗
https://blog.csdn.net/soslinken/article/details/53021510
=========================================
分割线来啦,2018.12.18更新
有同学反映topic订阅之后没有回调call方法。老夫特意从服务器端推送了消息到之前做的apk端,发现没有问题。几经讨论,后来此同学发现是topic订阅的参数不正确,需要加入自己的链接。如下:
mStompClient.topic("/queue/"+"自己的链接").subscribe(topicMessage -> {
Log.d("listenStomp", topicMessage.getPayload());
});
//要这种形式才能正常log,这么写就能使用成功,迷之问题。
看来是跟服务器端STOMP版本有关系。老夫之前跟同事联调的时候,比较幸运,并未遇到此问题。
特意更新记录下这个坑。具体请点击以下链接
https://github.com/NaikSoftware/StompProtocolAndroid/issues/130