简体   繁体   中英

Multiple connections websocket in okhttp

I am developed websocket server using nodejs (ws library)

I want to add chat module to android application. I am using okhttp for websocket client. When connect from device it is working. But when connect second device it is not working. Only first device websocket.on("message") event emitter responds. Another devices not listen onMessage. Only A device listen A. B->B

How to configure that onMessage works on all devices.

java client:

class SConnection {
    SConnection(String url) {
        mClient = new OkHttpClient.Builder()
                .readTimeout(3,  TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .build();

        mServerUrl = url;
    }

    public enum ConnectionStatus {
        DISCONNECTED,
        CONNECTED
    }

    public interface ServerListener {
        void onNewMessage(String message);
        void onStatusChange(ConnectionStatus status);
    }

    private WebSocket mWebSocket;
    private OkHttpClient mClient;
    private String mServerUrl;
    private Handler mMessageHandler;
    private Handler mStatusHandler;
    private ServerListener mListener;


    public class SocketListener extends WebSocketListener {
        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            Message m = mStatusHandler.obtainMessage(0, ConnectionStatus.CONNECTED);
            mStatusHandler.sendMessage(m);
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            Message m = mMessageHandler.obtainMessage(0, text);
            mMessageHandler.sendMessage(m);
        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            Message m = mStatusHandler.obtainMessage(0, ConnectionStatus.DISCONNECTED);
            mStatusHandler.sendMessage(m);
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            disconnect();
        }
    }

    void connect(ServerListener listener) {
        Request request = new Request.Builder()
                .url(mServerUrl)
                .build();
        mWebSocket = mClient.newWebSocket(request, new SocketListener());
        mListener = listener;
        mMessageHandler = new Handler(msg -> {mListener.onNewMessage((String) msg.obj);  return true;});
        mStatusHandler = new Handler(msg -> { mListener.onStatusChange((ConnectionStatus) msg.obj);   return true;});
    }

    void disconnect() {
        mWebSocket.cancel();
        mListener = null;
        mMessageHandler.removeCallbacksAndMessages(null);
        mStatusHandler.removeCallbacksAndMessages(null);
    }

    void sendMessage(String message) {
        mWebSocket.send(message);
    }

websocket server in nodejs:

module.exports = (httpsServer) => {

    const WebSocketServer = require('ws').Server;
    const wss = new WebSocketServer({
        server: httpsServer
    });

    wss.on('connection', function connection(ws) {
        console.log('connected');

        ws.on('message', function incoming(message) {
            ...
            ws.send(JSON.stringify(response));
        });
    });
    wss.on('close', function close() {
        console.log('disconnected');
    });
};

Maybe adding this solve problem, but how?

{'force new connection':true} 

First understand the issue , read all comments :

wss.on('connection', function connection(ws) {

    // So here ws is the user got connected
    console.log('connected');    

    // This will be fired when connected user send message
    ws.on('message', function incoming(message) {
        ...
        // this will send message to the same user
        ws.send(JSON.stringify(response));
    });

});

Solution : So all you need to do is get all clients and send it to all expect self , this is how you can do that :

ws.on('message', function incoming(data) {
    // Broadcast to everyone else.
    wss.clients.forEach(function each(client) {
        if (client !== ws && client.readyState === WebSocket.OPEN) {
            client.send(data);
        }
    });
});

For more detail DO READ

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM