概述
现在一款成熟的app一般都会具备长连接推送功能,那么我们要想项目具备长连接的功能现在又两种选择的方案,一种基于原生tcp协议的socket长连接,另外一种基于ws协议的websocket的长连接,今天我们演示两种socket长连接的实现集成方式(1、基于Oksocet框架实现socket长连接 2、基于OKhttp的实现的websocket的链接)下面分别是引用的连接
implementation 'com.squareup.okhttp3:okhttp:3.10.0' (websocket实现)
implementation 'com.tonystark.android:socket:3.1.0' (socket实现)
我是基于我现在公司的长连接来做得测试,我们公司为了兼容客户端和小程序,针对socket和websocket都做了兼容,做了两种方案,我就以这两种方案来讲解下我的实现历程
1.这是websocket连接的监听累,针对连接成功,连接失败和数据接收的回调
public class EchoWebSocketListener extends WebSocketListener {
Gson gson = new Gson();
private disConnectListener listener;
public EchoWebSocketListener(disConnectListener listener) {
this.listener = listener;
}
@Override
public void onOpen(WebSocket webSocket, Response response) {
}
@Override
public void onMessage(WebSocket webSocket, String text) {
AuthBean authBean = gson.fromJson(text, AuthBean.class);
if (TextUtils.equals(authBean.getCmd(), "auth1")) { //发送认证消息
String encode = MD5Utils.encode(authBean.getResult().getSeed() + "6PIRqVw3cRm84dKVg"); //由于是公司在线业务,所以加密串不能展示,原理是做MD5秘钥签名
String s = sendData(encode);
webSocket.send(s);
}
output("onMessage: " + text);
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
output("onMessage byteString: " + bytes);
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(1000, null);
output("onClosing: " + code + "/" + reason);
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
output("onClosed: " + code + "/" + reason);
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
output("onFailure: " + t.getMessage());
listener.reconnect();
}
private void output(String params) {
System.out.println(params);
}
private String sendData(String sign) {
String jsonHead = "";
Map<String, Object> mapHead = new HashMap<>();
mapHead.put("cmd", "auth2");
mapHead.put("msg_id", "1");
mapHead.put("authCode", sign);
mapHead.put("userId", "111");
jsonHead = buildRequestParams(mapHead);
Log.e("TAG", "sendData: " + jsonHead);
return jsonHead;
}
public static String buildRequestParams(Object params) {
Gson gson = new Gson();
String jsonStr = gson.toJson(params);
return jsonStr;
}
//定义失败回调的接口
interface disConnectListener {
void reconnect();
}
}
2、这是连接的类的具体的实现,通过handler实现心跳的发送,在创建监听类的时候,实现失败重连机制,界面销毁的时候,断开连接
public class OkhttpActivity extends AppCompatActivity {
private OkHttpClient client;
private long sendTime = 0L;
// 发送心跳包
private Handler mHandler = new Handler();
// 每隔2秒发送一次心跳包,检测连接没有断开
private static final long HEART_BEAT_RATE = 2 * 1000;
// 发送心跳包
private Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
String message = sendData();
mSocket.send(message);
sendTime = System.currentTimeMillis();
}
if (mHandler != null) {
mHandler.postDelayed(this, HEART_BEAT_RATE); //每隔一定的时间,对长连接进行一次心跳检测
}
}
};
private WebSocket mSocket;
private Request request;
private EchoWebSocketListener listener;
private String sendData() {
String jsonHead = "";
Map<String, Object> mapHead = new HashMap<>();
mapHead.put("cmd", "wd_heartbeat");
jsonHead = buildRequestParams(mapHead);
Log.e("TAG", "sendData: " + jsonHead);
return jsonHead;
}
public static String buildRequestParams(Object params) {
Gson gson = new Gson();
String jsonStr = gson.toJson(params);
return jsonStr;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_okhttp);
listener = new EchoWebSocketListener(new EchoWebSocketListener.disConnectListener() {
@Override
public void reconnect() {
if(mHandler!=null){
mSocket = client.newWebSocket(request, listener);
}
}
});
// Request request = new Request.Builder().url("ws://echo.websocket.org").build();
request = new Request.Builder().url("wss://xxxxxx/ws").build();
client = new OkHttpClient();
mSocket = client.newWebSocket(request, listener);
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
mHandler = null;
mSocket.cancel();
mSocket.close(1000,null);
}
}
日志输出:(服务端做了auth的认证,首次连接成功要认证,认证通过才能发送消息)
/*******************Socket实现socket长连接的实现**************************************/
按照下面代码创建socket长连接,界面销毁的时候断开连接(注意的时候:在接收到心跳包的时候,要通过判断是否是接收的心跳包的回调,对接收的数据进行框架的喂狗操作,如果没有这一步操作的话,监控狗会自动断开连接//进行心跳包的喂狗操作 if (TextUtils.equals(authBean.getCmd(), "wd_heartbeat")) { manager.getPulseManager().feed(); })
//连接参数设置(IP,端口号),这也是一个连接的唯一标识,不同连接,该参数中的两个值至少有其一不一样
ConnectionInfo info = new ConnectionInfo(
"jdsim.jindashi.cn", 9527);
//调用OkSocket,开启这次连接的通道,拿到通道Manager
manager = OkSocket.open(info);
//注册Socket行为监听器,SocketActionAdapter是回调的Simple类,其他回调方法请参阅类文档
manager.registerReceiver(new SocketActionAdapter() {
@Override
public void onSocketConnectionSuccess(Context context, ConnectionInfo info, String action) {
Toast.makeText(context, "连接成功", Toast.LENGTH_SHORT).show();
manager.getPulseManager().setPulseSendable(new TestSendData()).pulse();//发送心跳
}
@Override
public void onSocketReadResponse(Context context, ConnectionInfo info, String action, OriginalData data) {
byte[] bodyBytes = data.getBodyBytes();
try {
String s = new String(bodyBytes, "UTF-8");
// System.out.println((String)bodyBytes);
AuthBean authBean = gson.fromJson(s, AuthBean.class);
if (TextUtils.equals(authBean.getCmd(), "auth1")) {
manager.send(new SendAuthData(authBean.getResult().getSeed()));
// manager.getPulseManager().setPulseSendable(new TestSendData()).pulse();//发送心跳
}
//进行心跳包的喂狗操作
if (TextUtils.equals(authBean.getCmd(), "wd_heartbeat")) {
manager.getPulseManager().feed();
}
System.out.println("响应输出" + s);
} catch (UnsupportedEncodingException e) {
System.out.println("数据异常NG>>>>>>>>");
e.printStackTrace();
}
}
});
//调用通道进行连接
manager.connect();
日志输出:
最后
以上就是眼睛大招牌为你收集整理的安卓中socket长连接和websocket长连接的实现的全部内容,希望文章能够帮你解决安卓中socket长连接和websocket长连接的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复