概述
本人原来是java工程师,但是最近没事就干起了android的活,我的具体需求是android使用websocket保持长连接 后台为nodejs 好了 不多说 开撸
nodejs方面使用的是nodejs-websocket,而不是http+ws+socket.io,使用后者在我的android代码会有bug:流意外断开(下图)java.io.IOException: unexpected end of stream on Connection 总之就是连接不上
为解决这个bug,困扰了我很久 查了很多资料 都是如下两图两种方法 还是不能解决 所以我就把想法放到了nodejs中 不使用socket.io 使用nodejs-websocket
说了这么多,放代码了nodejs:
//引入nodejs-websocket 如果报错 在cmd里命令:npm install nodejs-websocket
var ws= require("nodejs-websocket");
//广播通知方法 可有可无
const broadcast = (server, info) => {
console.log('broadcast', info)
server.connections.forEach(function(conn) {
conn.sendText(JSON.stringify(info))
})
}
var server = ws.createServer(function(conn){
//从前端收到信息
conn.on("text", function (str) {
//发送消息使用 conn.send("发送消息:"+str);
broadcast(server,str); //广播通知收到的消息
});
conn.on("close", function (code, reason ) {
console.log("退出了连接=========》close");
});
conn.on("error", function (code, reason) {
console.log("异常关闭");
});
}).listen(3000);
android方面代码:
- InitSocketThread.java 我们在线程里执行连接操作
package com.Piggysnow.RtcView.util;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.Log;
import com.Piggysnow.RtcView.MediaUtil;
import com.Piggysnow.RtcView.service.BackService;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class InitSocketThread extends Thread{
BackService service;
Handler serviceHandler;
public InitSocketThread(){}
public InitSocketThread(BackService service,Handler handler)
{
this.service = service;
this.serviceHandler=handler;
}
@Override
public void run() {
super.run();
try {
initSocket();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 心跳检测时间
*/
private static final long HEART_BEAT_RATE = 15 * 1000;//每隔15秒进行一次对长连接的心跳检测
private static final String WEBSOCKET_HOST_AND_PORT = "ws://192.168.8.104:3000";//可替换为自己的主机名和端口号
public static WebSocket mWebSocket;
// 初始化socket
public void initSocket() throws UnknownHostException, IOException {
Log.e("INITSOCKET", "initsocket in");
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5000, TimeUnit.MILLISECONDS).connectTimeout(6000,TimeUnit.MINUTES).build();
Request request = new Request.Builder()
.url(WEBSOCKET_HOST_AND_PORT).build();
Log.e("INITSOCKET", request.url().uri().toString());
client.newWebSocket(request, new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {//开启长连接成功的回调
super.onOpen(webSocket, response);
Log.e("INITSOCKET", "initsocket onOpen");
mWebSocket = webSocket;
mWebSocket.send("MyId?id=123456"); //向服务器发送id
}
@Override
public void onMessage(WebSocket webSocket, String text) {//接收消息的回调
super.onMessage(webSocket, text);
Log.e("SENDTEXT", text); //输入消息
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
super.onMessage(webSocket, bytes);
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
super.onClosing(webSocket, code, reason);
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
Log.e("INITSOCKET", "initsocket onClosed");
super.onClosed(webSocket, code, reason);
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) {//长连接连接失败的回调
mWebSocket=webSocket;
Log.e("INITSOCKET", "initsocket onFailure");
super.onFailure(webSocket, t, response);
t.printStackTrace();
}
});
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
}
private static long sendTime = 0L;
// 发送心跳包
private static Handler mHandler = new Handler();
private static Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
if(mWebSocket==null)
{
mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的时间,对长连接进行一次心跳检测
return;
}
boolean isSuccess = mWebSocket.send("");//发送一个空消息给服务器,通过发送消息的成功失败来判断长连接的连接状态
if (!isSuccess) {//长连接已断开
mHandler.removeCallbacks(heartBeatRunnable);
mWebSocket.cancel();//取消掉以前的长连接
new InitSocketThread().start();//创建一个新的连接
} else {//长连接处于连接状态
}
sendTime = System.currentTimeMillis();
}
mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的时间,对长连接进行一次心跳检测
}
};
}
- BackService
package com.Piggysnow.RtcView.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import com.Piggysnow.RtcView.util.InitSocketThread;
public class BackService extends Service {
protected Handler handler=new Handler();
@Override
public void onCreate() {
super.onCreate();
Log.e("INIT", "Backserver init on create");
new InitSocketThread(this,handler).start();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public class MyBinder extends Binder {
public BackService getMyService(){
return BackService.this;
}
}
/**
* 在Service中定义这个方法,用于测试
* @return
*/
public String getAuthorName(){
return "guchuanhang";
}
@Override
public void onDestroy() {
super.onDestroy();
if (InitSocketThread.mWebSocket != null) {
InitSocketThread.mWebSocket.close(1000, null);
}
}
public static void main(String[] args) {
BackService service=new BackService();
service.onCreate();
}
}
- Activity类中需要新增的代码(记住是新增)
BackService myService=null;
ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService= ((BackService.MyBinder) service).getMyService();
String authorName = myService.getAuthorName();
Toast.makeText(UnityPlayerActivity.this, "author name is: " + authorName,
Toast.LENGTH_LONG).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
- Activity类onCreate方法中需要新增的代码(记住是新增)
Intent myServiceIntent = new Intent(UnityPlayerActivity.this, BackService.class);
bindService(myServiceIntent, mServiceConnection,
Context.BIND_AUTO_CREATE);
然后就到这里结束了 希望大家能够连接成功!!!欢迎大家评论
最后
以上就是端庄河马为你收集整理的android使用websocket保持长连接 后台为nodejs带心跳检测的全部内容,希望文章能够帮你解决android使用websocket保持长连接 后台为nodejs带心跳检测所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复