package com.example.ewdatasystem_android.websocket; import com.example.util.LogUtil; import org.java_websocket.WebSocket; import org.java_websocket.client.WebSocketClient; import org.java_websocket.framing.Framedata; import org.java_websocket.handshake.ServerHandshake; import java.net.URI; import java.net.URISyntaxException; import java.util.Timer; import java.util.TimerTask; /** * 2020/1/6 10:29 * * @description *转载的,忘记原链接了。。。。 * */ public class MyWSClient extends WebSocketClient { private static MyWSClient instance; private static URI sUri; private long mWsXinTiao; private Timer mTimer; /** * 之所以要用单例模式,是因为需要重连导致存在多线程并发的问题,会导致同时接收到多条相同信息,所以只能有一个实例。 * 不使用的话可能报错(WebSocketClient objects are not reuseable) * <p> * 根据https://blog.csdn.net/hizhangyuping/article/details/81779364 * * @return */ public static MyWSClient getInstance() { if (instance == null) { synchronized (MyWSClient.class) { if (instance == null) { instance = new MyWSClient(sUri); } } } return instance; } public MyWSClient(URI serverUri) { super(serverUri); } /** * step 1: * 需要先调用,设置服务端的 url */ public static void setUri(String url) { try { sUri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } } /** * step 2:连接 websocket */ public void onConnect() { //设置10秒后开始ping setConnectionLostTimeout(1000); //开始连接 connect(); } /** * 连接成功 * * @param handshakedata */ @Override public void onOpen(ServerHandshake handshakedata) { LogUtil.e("连接成功"); clientLisenter.onOpen(handshakedata); } /** * 接收到的消息 * * @param message */ @Override public void onMessage(String message) { LogUtil.e("接收到的消息:" + message); clientLisenter.onMessage(message); // EventBus.getDefault().post(new SocketMessage(message)); } /** * 断开连接 * * @param code * @param reason * @param remote true 主机断开 false 客户端主动断开 */ @Override public void onClose(int code, String reason, boolean remote) { clientLisenter.onClose(code, reason, remote); if (remote) { onReconnect(); } } /** * 连接出错 * * @param ex */ @Override public void onError(Exception ex) { if (ex != null) { clientLisenter.onError(ex); } onReconnect(); } /** * ping通时的方法 * <p> * 此方法可以判断websocket是否连接,如果超过超就重新连接 * <p> * 我使用的是EventBus通信 通信比较方便 * * @param conn * @param f */ @Override public void onWebsocketPong(WebSocket conn, Framedata f) { super.onWebsocketPong(conn, f); clientLisenter.onWebsocketPong(conn, f); mWsXinTiao = System.currentTimeMillis(); mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { if (System.currentTimeMillis() - mWsXinTiao > 30 * 1000) { //接收不到ping时重新连接 onReconnect(); } } }, 2000, 35 * 1000);//比心跳时间多一点 也没事。 // EventBus.getDefault().post(new SocketMessage("ping")); } /** * 重新连接方法 * <p> * 先关闭连接再使用reconnect()方法 * <p> * reconnect()方法要放在子线程里否则会报错 * <p> * You cannot initialize a reconnect out of the websocket thread. Use reconnect in another thread to insure a successful cleanup. * (无法从WebSocket线程初始化重新连接。在另一个线程中使用Reconnect以确保成功清理。) */ public void onReconnect() { onCloseWebsocket(); clientLisenter.onReconnect(); if (!isOpen()) { Runnable sendable = new Runnable() { @Override public void run() { LogUtil.e("websocket reconnect"); reconnect(); } }; new Thread(sendable).start(); } } /** * 发送信息 * * @param msg */ public void sendMsg(String msg) { if (isOpen()) this.send(msg); LogUtil.e("ws- 发送 message:" + msg); } /** * 关闭websocket连接 */ public void onCloseWebsocket() { try { this.close(); } catch (Exception e) { e.printStackTrace(); } } private ClientLisenter clientLisenter; public interface ClientLisenter { void onOpen(ServerHandshake handshakedata); void onMessage(String message); void onClose(int code, String reason, boolean remote); void onError(Exception ex); void onWebsocketPong(WebSocket conn, Framedata f); void onReconnect(); } public void setClientLisenter(ClientLisenter clientLisenter) { this.clientLisenter = clientLisenter; } //使用 private void method(){ // try { // //设置连接地址 WEB_SOCKET_HOST时你的websocket地址 // MyWSClient.setUri(returnUrl("18824403202","12345")); // //开始连接 // MyWSClient.getInstance().onConnect(); // MyWSClient.getInstance().setClientLisenter(new MyWSClient.ClientLisenter() { // @Override // public void onOpen(ServerHandshake handshakedata) { // LogUtil.e("onOpen"); // } // // @Override // public void onMessage(String message) { // LogUtil.e("onMessage:"+message); // } // // @Override // public void onClose(int code, String reason, boolean remote) { // LogUtil.e(remote ? "服务器Cut" : "客户端Cut"); // } // // @Override // public void onError(Exception ex) { // LogUtil.e(String.format("websocket 出现错误,错误原因:%s\n", ex.getMessage())); // } // // @Override // public void onWebsocketPong(WebSocket conn, Framedata f) { // LogUtil.e("onWebsocketPong"); // } // // @Override // public void onReconnect() { // LogUtil.e("onReconnect"); // } // }); // } catch (Exception e) { // LogUtil.e("错误" + e.getMessage()); // MyWSClient.getInstance().onReconnect(); // } } }