赞
踩
现在一款成熟的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();
日志输出:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。