简体   繁体   English

使用Android在socket.io中的每第二个连接上广播到房间的工程

[英]broadcast to room works on every second connection in socket.io with android

I created socket io server using nodejs and from android connected to the server. 我使用nodejs并从连接到服务器的android创建了套接字io服务器。

I am using io. 我正在使用io。 socket: socket. 套接字:套接字。 io-client: 1.0.0 library for android. io-client:适用于Android的1.0.0库。

The problem was when I try to send message when open app it works. 问题是当我尝试在打开的应用程序运行时发送消息时。 But when I reconnect socket I it not works. 但是当我重新连接套接字时,它不起作用。 Just when second reconnection it works. 仅在第二次重新连接时有效。 Every second connection. 每秒连接一次。 Previously I tried to add users to client variable, then emit to socketid. 以前,我尝试将用户添加到客户端变量,然后将其发出给socketid。 But now I am using the rooms. 但是现在我正在使用房间。

I think socket io server store old room, and for second connection it works properly 我认为套接字io服务器存储了旧房间,对于第二次连接,它可以正常工作

How can I refresh rooms before broadcast or broadcast last updated rooms? 如何在广播之前广播房间或广播最近更新的房间?

server.js server.js

module.exports = (httpsServer) => {
    const io = require('socket.io')(httpsServer, {
        log: false,
        cookie: false,
        multiplex: false
    });
    io.set({
        transports: ['websocket', 'polling']
    });
    io.on('connection', (socket) => {

        ocket.on('join', (id) => {
            console.log(id + " joined");
            socket.join(id);
        });
        socket.on('disconnect', (id) => {
            console.log(id + " leaved");
            socket.leave(id);
        });

        socket.on('messageToUser', (endUserId, msg) => {
            console.log("admin broadcast to: " + endUserId);
            socket.broadcast.to(endUserId).emit('inbox', {
                senderId: '1',
                endUser: endUserId,
                message: msg
            });
            socket.emit('inbox', {
                senderId: '1',
                endUser: endUserId,
                message: msg
            });
        });
    });
};

App.java App.java

public class App extends Application {

    private Socket mSocket;
    {
        try {
            IO.Options opts = new IO.Options();
            opts.secure = true;
            opts.transports = new String[]{WebSocket.NAME};
            opts.reconnection = true;
            opts.forceNew = true;
            opts.multiplex = false;
            mSocket = IO.socket("...",opts);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public Socket getSocket() {
        return mSocket;
    }
}

ChatActivity.java ChatActivity.java

    App app = (App) getApplication();
        mSocket = app.getSocket();
        mSocket.on(Socket.EVENT_CONNECT,onConnect);
        mSocket.on(Socket.EVENT_DISCONNECT,onDisconnect);
        mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
        mSocket.on("inbox", inbox);
        mSocket.connect();
sendButton.setOnClickListener(v -> {
            if (!mSocket.connected()) return;
            if(!messageEditText.getText().toString().trim().isEmpty()){
                mSocket.emit("messageToUser", endUserId, messageEditText.getText().toString()); 
                messageEditText.setText("");
            }
        });

private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(!isConnected) {
                        mSocket.emit("join", userInfoSharedP.getUserId()); 
 isConnected = true;
                    }
                }
            });
        }
    };

...

您需要为ChatActivity或至少asynctask提供后台或前台服务,也可以为套接字实例使用全局公共变量,这是正常运行所必需的

I found a problem. 我发现了一个问题。 I am using pm2 process manager. 我正在使用pm2进程管理器。 And I run PM2 with its built in load balancer. 我使用内置的负载均衡器运行PM2。 Something like this: 像这样:

pm2 start server -i 2

And when I stop pm2 and start own node server, it works properly. 当我停止pm2并启动自己的节点服务器时,它可以正常工作。 I think problem in load balancing with 2 core. 我认为2核心负载平衡中存在问题。 And when I connect socket every second connection emit works. 当我连接套接字时,第二个连接就会发出信号。 It is because of dividing processes into two. 这是因为将过程分为两个。

Firstly install redis 首先安装redis

# on mac
brew install redis
sudo brew services start redis

Then install the socket.io redis adapter in project 然后在项目中安装socket.io redis适配器

npm i socket.io-redis --save

Finally, 最后,

const sockets = require('socket.io')
const redis = require('socket.io-redis')

const bindListeners = (io) => {
  io.on('connection', (socket) => {
    console.log(`${socket.id} connected`)
  })
}

module.exports = (server) => {
  const io = sockets(server, {
    transports: [ 'websocket', 'polling' ]
  })
  // Add the redis adapter
  io.adapter(redis({ host: 'localhost', port: 6379 }))   
  bindListeners(io)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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