首页 > 编程知识 正文

长连接 websocket,java websocket 长连接

时间:2023-05-06 04:23:29 阅读:224972 作者:885

现在一款成熟的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();

日志输出:

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。