当前位置:   article > 正文

安卓中socket长连接和websocket长连接的实现_app长连接基于的是websocket吗

app长连接基于的是websocket吗

现在一款成熟的app一般都会具备长连接推送功能,那么我们要想项目具备长连接的功能现在又两种选择的方案,一种基于原生tcp协议的socket长连接,另外一种基于ws协议的websocket的长连接,今天我们演示两种socket长连接的实现集成方式(1、基于Oksocet框架实现socket长连接   2、基于OKhttp的实现的websocket的链接)下面分别是引用的连接

  1. implementation 'com.squareup.okhttp3:okhttp:3.10.0' (websocket实现)
  2. implementation 'com.tonystark.android:socket:3.1.0' (socket实现)

我是基于我现在公司的长连接来做得测试,我们公司为了兼容客户端和小程序,针对socket和websocket都做了兼容,做了两种方案,我就以这两种方案来讲解下我的实现历程

1.这是websocket连接的监听累,针对连接成功,连接失败和数据接收的回调

  1. public class EchoWebSocketListener extends WebSocketListener {
  2. Gson gson = new Gson();
  3. private disConnectListener listener;
  4. public EchoWebSocketListener(disConnectListener listener) {
  5. this.listener = listener;
  6. }
  7. @Override
  8. public void onOpen(WebSocket webSocket, Response response) {
  9. }
  10. @Override
  11. public void onMessage(WebSocket webSocket, String text) {
  12. AuthBean authBean = gson.fromJson(text, AuthBean.class);
  13. if (TextUtils.equals(authBean.getCmd(), "auth1")) { //发送认证消息
  14. String encode = MD5Utils.encode(authBean.getResult().getSeed() + "6PIRqVw3cRm84dKVg"); //由于是公司在线业务,所以加密串不能展示,原理是做MD5秘钥签名
  15. String s = sendData(encode);
  16. webSocket.send(s);
  17. }
  18. output("onMessage: " + text);
  19. }
  20. @Override
  21. public void onMessage(WebSocket webSocket, ByteString bytes) {
  22. output("onMessage byteString: " + bytes);
  23. }
  24. @Override
  25. public void onClosing(WebSocket webSocket, int code, String reason) {
  26. webSocket.close(1000, null);
  27. output("onClosing: " + code + "/" + reason);
  28. }
  29. @Override
  30. public void onClosed(WebSocket webSocket, int code, String reason) {
  31. output("onClosed: " + code + "/" + reason);
  32. }
  33. @Override
  34. public void onFailure(WebSocket webSocket, Throwable t, Response response) {
  35. output("onFailure: " + t.getMessage());
  36. listener.reconnect();
  37. }
  38. private void output(String params) {
  39. System.out.println(params);
  40. }
  41. private String sendData(String sign) {
  42. String jsonHead = "";
  43. Map<String, Object> mapHead = new HashMap<>();
  44. mapHead.put("cmd", "auth2");
  45. mapHead.put("msg_id", "1");
  46. mapHead.put("authCode", sign);
  47. mapHead.put("userId", "111");
  48. jsonHead = buildRequestParams(mapHead);
  49. Log.e("TAG", "sendData: " + jsonHead);
  50. return jsonHead;
  51. }
  52. public static String buildRequestParams(Object params) {
  53. Gson gson = new Gson();
  54. String jsonStr = gson.toJson(params);
  55. return jsonStr;
  56. }
  57. //定义失败回调的接口
  58. interface disConnectListener {
  59. void reconnect();
  60. }
  61. }

2、这是连接的类的具体的实现,通过handler实现心跳的发送,在创建监听类的时候,实现失败重连机制,界面销毁的时候,断开连接

  1. public class OkhttpActivity extends AppCompatActivity {
  2. private OkHttpClient client;
  3. private long sendTime = 0L;
  4. // 发送心跳包
  5. private Handler mHandler = new Handler();
  6. // 每隔2秒发送一次心跳包,检测连接没有断开
  7. private static final long HEART_BEAT_RATE = 2 * 1000;
  8. // 发送心跳包
  9. private Runnable heartBeatRunnable = new Runnable() {
  10. @Override
  11. public void run() {
  12. if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
  13. String message = sendData();
  14. mSocket.send(message);
  15. sendTime = System.currentTimeMillis();
  16. }
  17. if (mHandler != null) {
  18. mHandler.postDelayed(this, HEART_BEAT_RATE); //每隔一定的时间,对长连接进行一次心跳检测
  19. }
  20. }
  21. };
  22. private WebSocket mSocket;
  23. private Request request;
  24. private EchoWebSocketListener listener;
  25. private String sendData() {
  26. String jsonHead = "";
  27. Map<String, Object> mapHead = new HashMap<>();
  28. mapHead.put("cmd", "wd_heartbeat");
  29. jsonHead = buildRequestParams(mapHead);
  30. Log.e("TAG", "sendData: " + jsonHead);
  31. return jsonHead;
  32. }
  33. public static String buildRequestParams(Object params) {
  34. Gson gson = new Gson();
  35. String jsonStr = gson.toJson(params);
  36. return jsonStr;
  37. }
  38. @Override
  39. protected void onCreate(Bundle savedInstanceState) {
  40. super.onCreate(savedInstanceState);
  41. setContentView(R.layout.activity_okhttp);
  42. listener = new EchoWebSocketListener(new EchoWebSocketListener.disConnectListener() {
  43. @Override
  44. public void reconnect() {
  45. if(mHandler!=null){
  46. mSocket = client.newWebSocket(request, listener);
  47. }
  48. }
  49. });
  50. // Request request = new Request.Builder().url("ws://echo.websocket.org").build();
  51. request = new Request.Builder().url("wss://xxxxxx/ws").build();
  52. client = new OkHttpClient();
  53. mSocket = client.newWebSocket(request, listener);
  54. mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);
  55. }
  56. @Override
  57. protected void onDestroy() {
  58. super.onDestroy();
  59. mHandler.removeCallbacksAndMessages(null);
  60. mHandler = null;
  61. mSocket.cancel();
  62. mSocket.close(1000,null);
  63. }
  64. }

日志输出:(服务端做了auth的认证,首次连接成功要认证,认证通过才能发送消息)

 

/*******************Socket实现socket长连接的实现**************************************/

 

按照下面代码创建socket长连接,界面销毁的时候断开连接(注意的时候:在接收到心跳包的时候,要通过判断是否是接收的心跳包的回调,对接收的数据进行框架的喂狗操作,如果没有这一步操作的话,监控狗会自动断开连接//进行心跳包的喂狗操作 if (TextUtils.equals(authBean.getCmd(), "wd_heartbeat")) { manager.getPulseManager().feed(); })

  1. //连接参数设置(IP,端口号),这也是一个连接的唯一标识,不同连接,该参数中的两个值至少有其一不一样
  2. ConnectionInfo info = new ConnectionInfo(
  3. "jdsim.jindashi.cn", 9527);
  4. //调用OkSocket,开启这次连接的通道,拿到通道Manager
  5. manager = OkSocket.open(info);
  6. //注册Socket行为监听器,SocketActionAdapter是回调的Simple类,其他回调方法请参阅类文档
  7. manager.registerReceiver(new SocketActionAdapter() {
  8. @Override
  9. public void onSocketConnectionSuccess(Context context, ConnectionInfo info, String action) {
  10. Toast.makeText(context, "连接成功", Toast.LENGTH_SHORT).show();
  11. manager.getPulseManager().setPulseSendable(new TestSendData()).pulse();//发送心跳
  12. }
  13. @Override
  14. public void onSocketReadResponse(Context context, ConnectionInfo info, String action, OriginalData data) {
  15. byte[] bodyBytes = data.getBodyBytes();
  16. try {
  17. String s = new String(bodyBytes, "UTF-8");
  18. // System.out.println((String)bodyBytes);
  19. AuthBean authBean = gson.fromJson(s, AuthBean.class);
  20. if (TextUtils.equals(authBean.getCmd(), "auth1")) {
  21. manager.send(new SendAuthData(authBean.getResult().getSeed()));
  22. // manager.getPulseManager().setPulseSendable(new TestSendData()).pulse();//发送心跳
  23. }
  24. //进行心跳包的喂狗操作
  25. if (TextUtils.equals(authBean.getCmd(), "wd_heartbeat")) {
  26. manager.getPulseManager().feed();
  27. }
  28. System.out.println("响应输出" + s);
  29. } catch (UnsupportedEncodingException e) {
  30. System.out.println("数据异常NG>>>>>>>>");
  31. e.printStackTrace();
  32. }
  33. }
  34. });
  35. //调用通道进行连接
  36. manager.connect();

日志输出:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/1021595
推荐阅读