Android webSocket应用Demo,推送、即时通信、心跳重连。可实现简单聊天、服务端推送消息到客服端等功能。(java-webSocket)

使用java-webSocket开源库

第一步:添加依赖

//webSocket
implementation "org.java-websocket:Java-WebSocket:1.5.1"

第二步:创建一个绑定服务

要发送消息需要调用WebSocketClient的send方法,它是写在我们的service中,所以需要BindService来实现。

public class WebSocketService extends Service {

    private static final String TAG = "WebSocketService";
    private static final long HEART_BEAT_RATE = 5 * 1000;//每隔5秒进行一次对长连接的心跳检测
    private final HeartHandler mHeartHandler = new HeartHandler(this);
    private WebSocketClient client;
    private ServiceBinder binder = new ServiceBinder();

    private String roomId;
    private String userId;
    private Messenger mMessenger;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        roomId = intent.getStringExtra("roomId");
        userId = intent.getStringExtra("userId");
        if (mMessenger == null) {
            mMessenger = (Messenger)intent.getExtras().get("handler");
        }
        initSocketClient();
        return this.binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        try {
            Log.d(TAG, "onDestroy: socket service onDestroy()");
            client.close();
            mHeartHandler.removeCallbacksAndMessages(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public final class ServiceBinder extends Binder {
        public WebSocketService getService() {
            return WebSocketService.this;
        }
    }

    /**
     * 初始化webSocket
     */
    public void initSocketClient(){
        //TODO webSocket地址
        String webSocketUrl = "ws://...";
        try {
            Log.d(TAG, "initSocketClient: roomId---" + roomId);
            client = new WebSocketClient(new URI(webSocketUrl + roomId + "/" + userId),new Draft_6455()) {
                @Override
                public void onWebsocketPong(WebSocket conn, Framedata f) {
                    super.onWebsocketPong(conn, f);
                    Log.d(TAG, "onWebsocketPong: " + f.getPayloadData().toString());
                    Log.d(TAG, "onWebsocketPong: socket ping" + f.getOpcode());
                }

                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    // 连接打开以后的回调
                    Log.d(TAG, "onOpen: ");
                
                }

                @Override
                public void onMessage(String message) {
                    // 收到消息的回调
                    Log.d(TAG, "onMessage: socket接收服务器发来的消息:" + message);
                    Message handlerMessage = Message.obtain();
                    handlerMessage.what = HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS;
                    handlerMessage.obj = message;
                    try {
                        mMessenger.send(handlerMessage);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(Exception ex) {
                    // 连接出错的回调
                    Log.d(TAG, "onError: " + ex);
                    reconnectWs();
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    // 连接关闭的回调, remote如果为true表示被服务端cut掉了
                    Log.d(TAG, "onClose: ");
                    reconnectWs();
                }

                @Override
                public void onMessage(ByteBuffer bytes) {
                    super.onMessage(bytes);
                    Log.d(TAG, "onMessage: socket bytebuffer bytes---" + bytes);
                }

                @Override
                protected void onSetSSLParameters(SSLParameters sslParameters) {
//                    super.onSetSSLParameters(sslParameters);
                    try{
                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            super.onSetSSLParameters(sslParameters);
                        }
                    }catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            mHeartHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
            client.connectBlocking();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过webSocket发送消息
     * @param sMessage
     */
    public void sendMessage(String sMessage){
        if (client == null || client.isClosed()) {
            Log.d(TAG, "sendMessage: client is null or closed");
            return;
        }
        try {
            client.send(sMessage);
            Log.d(TAG, "sendMessage: 发送---" + sMessage);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 静态内部类Handler
     */
    private static class HeartHandler extends Handler {
        private final WeakReference<WebSocketService> mService;

        public HeartHandler(WebSocketService service) {
            this.mService = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            WebSocketService webSocketService = mService.get();
            if (webSocketService!=null) {

            }
        }
    }

    //心跳线程
    private final Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "run: 扑通");
            if (client != null) {
                if (client.isClosed()) {
                    reconnectWebSocket();
                    return;
                }
            } else {
                //如果client已为空,重新初始化websocket
                initSocketClient();
                return;
            }
            //定时对长连接进行心跳检测
            mHeartHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };

    /**
     * 开启重连
     */
    private void reconnectWs() {
        mHandler.removeCallbacks(heartBeatRunnable);
        try {
            //重连
            mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
            client.reconnectBlocking();
            Log.d(TAG, "run: reconnectWs---心跳重连");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

2.1:Service的onBind

@Override
public IBinder onBind(Intent intent) {
    roomId = intent.getStringExtra("roomId");
    userId = intent.getStringExtra("userId");
    if (mMessenger == null) {
        mMessenger = (Messenger)intent.getExtras().get("handler");
    }
    return this.binder;
}

intent中是从Activity传递过来的参数,创建WebSocketClient的时候需要roomId,和userId,roomId相同的用户会进入同一个webSocket房间,发送的消息互相能接收,userId用来区分不同的用户。

Messenger用于接收从Activity传递过来的Handledr

2.2 连接webSocket服务(进入webSocket房间)

    /**
     * 初始化webSocket
     */
    public void initSocketClient(){
        //TODO webSocket地址
        String webSocketUrl = "ws://...";
        try {
            Log.d(TAG, "initSocketClient: roomId---" + roomId);
            client = new WebSocketClient(new URI(webSocketUrl + roomId + "/" + userId),new Draft_6455()) {
                @Override
                public void onWebsocketPong(WebSocket conn, Framedata f) {
                    super.onWebsocketPong(conn, f);
                    Log.d(TAG, "onWebsocketPong: " + f.getPayloadData().toString());
                    Log.d(TAG, "onWebsocketPong: socket ping" + f.getOpcode());
                }

                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    // 连接打开以后的回调
                    Log.d(TAG, "onOpen: ");
                   
                }

                @Override
                public void onMessage(String message) {
                    // 收到消息的回调
                    Log.d(TAG, "onMessage: socket接收服务器发来的消息:" + message);
                    Message handlerMessage = Message.obtain();
                    handlerMessage.what = HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS;
                    handlerMessage.obj = message;
                    try {
                        mMessenger.send(handlerMessage);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(Exception ex) {
                    // 连接出错的回调
                    Log.d(TAG, "onError: " + ex);
                    reconnectWebSocket();
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    // 连接关闭的回调, remote如果为true表示被服务端cut掉了
                    Log.d(TAG, "onClose: ");
                    if (remote) {
                        Log.d(TAG, "onClose: 服务器cut");
                        reconnectWebSocket();
                    }
                }

                @Override
                public void onMessage(ByteBuffer bytes) {
                    super.onMessage(bytes);
                    Log.d(TAG, "onMessage: socket bytebuffer bytes---" + bytes);
                }

                @Override
                protected void onSetSSLParameters(SSLParameters sslParameters) {
//                    super.onSetSSLParameters(sslParameters);
                    try{
                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            super.onSetSSLParameters(sslParameters);
                        }
                    }catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
            client.connectBlocking();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.3开启心跳

onOpen表示连接成功,此时需要开启心跳不断检测连接,防止中途断连

    private static final long HEART_BEAT_RATE = 5 * 1000;//每隔5秒进行一次对长连接的心跳检测
    private final HeartHandler mHeartHandler = new HeartHandler(this);


    /**
     * 静态内部类Handler
     */
    private static class HeartHandler extends Handler {
        private final WeakReference<WebSocketService> mService;

        public HeartHandler(WebSocketService service) {
            this.mService = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            WebSocketService webSocketService = mService.get();
            if (webSocketService!=null) {

            }
        }
    }

    //心跳线程
    private final Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "run: 扑通");
            if (client != null) {
                if (client.isClosed()) {
                    reconnectWebSocket();
                    return;
                }
            } else {
                //如果client已为空,重新初始化websocket
                initSocketClient();
                return;
            }
            //定时对长连接进行心跳检测
            mHeartHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };

2.4接收消息

onMessage表示接收到消息,可以把消息传递到Activity

@Override
public void onMessage(String message) {
    // 收到消息的回调
    Log.d(TAG, "onMessage: socket接收服务器发来的消息:" + message);
    Message handlerMessage = Message.obtain();
    handlerMessage.what = HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS;
    handlerMessage.obj = message;
    try {
        mMessenger.send(handlerMessage);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

第三步:在Activity中绑定服务,开启webSocket

public class WebSocketActivity extends AppCompatActivity {

    private static final String TAG = "WebSocketActivity";
    private final WebSocketHandler mHandler = new WebSocketHandler(this);
    private WebSocketService socketService;
    private ServiceConnection serviceConnection;
    private TextView tvState;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_socket);

        tvState = findViewById(R.id.act_webSocket_tv_state);
        openSocket();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (serviceConnection!=null) {
            unbindService(serviceConnection);
        }
    }

    /**
     * 开启webSocket接收服务端的事件推送
     */
    private void openSocket() {
        Intent socketInten = new Intent(this, WebSocketService.class);
        socketInten.putExtra("roomId", "111");
        socketInten.putExtra("userId", "222");
        socketInten.putExtra("handler",new Messenger(mHandler));

        try {
            serviceConnection = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    WebSocketService.ServiceBinder binder = (WebSocketService.ServiceBinder) service;
                    socketService = binder.getService();
                }

                @Override
                public void onServiceDisconnected(ComponentName name) {
                    Log.d(TAG, "onServiceDisconnected: ");
                }
            };
            this.bindService(socketInten, serviceConnection, Service.BIND_AUTO_CREATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送webSocket消息
     */
    private void sendMessage(String message) {
        socketService.sendMessage(message);
    }

    /**
     * 静态内部类Handler
     * 接收Service消息
     */
    private static class WebSocketHandler extends Handler {
        private final WeakReference<WebSocketActivity> mActivity;

        public WebSocketHandler(WebSocketActivity activity) {
            this.mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            WebSocketActivity activity = mActivity.get();
            if (activity!=null) {
                switch (msg.what) {
                    case HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS:
                        activity.tvState.setText(msg.obj.toString());
                        break;
                    default:
                        break;
                }
            }
        }
    }

}

第四步:发送消息

在Activity中调用sendMessage方法,传入String类型消息(封装成json),然后通过service中的sendMessage方法,调用WebSocketClient.send()

WebSocketActivity:---------------------
    /**
     * 发送webSocket消息
     */
    private void sendMessage(String message) {
        socketService.sendMessage(message);
    }


WebSocketService:----------------------
    /**
     * 通过webSocket发送消息
     * @param sMessage
     */
    public void sendMessage(String sMessage){
        if (client == null || client.isClosed()) {
            Log.d(TAG, "sendMessage: client is null or closed");
            return;
        }
        try {
            client.send(sMessage);
            Log.d(TAG, "sendMessage: 发送---" + sMessage);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

第五步:处理接收到的消息

    /**
     * 静态内部类Handler
     * 接收Service消息
     */
    private static class WebSocketHandler extends Handler {
        private final WeakReference<WebSocketActivity> mActivity;

        public WebSocketHandler(WebSocketActivity activity) {
            this.mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            WebSocketActivity activity = mActivity.get();
            if (activity!=null) {
                switch (msg.what) {
                    case HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS:
                        activity.tvState.setText(msg.obj.toString());
                        break;
                    default:
                        break;
                }
            }
        }
    }

该Handler是通过Intent将实例传递到Service,在Service中由Messenger接收,然后在webSocket的onMessage回调中通过Messenger将消息发送到Activity中的handleMessage方法。

demo资源地址:

WebSocket.rarAndroidjava-webSocket完整案例源码,推送,即时通信,双向通信,心跳重连-Android文档类资源-CSDN下载java-webSocket是免费的,集成java-webSocket开源而成的一个比较完整的dem更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_37980878/20710962?spm=1001.2014.3001.5503

猜你喜欢

转载自blog.csdn.net/qq_37980878/article/details/121700368