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

时间:2018-12-28 17:47:41

标签: android node.js sockets socket.io

我使用nodejs并从连接到服务器的android创建了套接字io服务器。

我正在使用io。套接字:套接字。 io-client:适用于Android的1.0.0库。

问题是当我尝试在打开的应用程序正常工作时发送消息时。但是当我重新连接套接字时,它不起作用。仅在第二次重新连接时有效。每秒连接一次。以前,我尝试将用户添加到客户端变量,然后将其发出给socketid。但是现在我正在使用房间。

我认为套接字io服务器存储了旧房间,对于第二次连接,它可以正常工作

如何在广播之前更新房间或广播最近更新的房间?

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

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

    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;
                    }
                }
            });
        }
    };

...

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

我发现了一个问题。我正在使用pm2进程管理器。我使用内置的负载均衡器运行PM2。像这样:

pm2 start server -i 2

当我停止pm2并启动自己的节点服务器时,它可以正常工作。我认为2核心负载平衡中存在问题。当我连接套接字时,第二个连接就会发出信号。这是因为将流程分为两个。

首先安装redis

# on mac
brew install redis
sudo brew services start redis

然后在项目中安装socket.io redis适配器

npm i socket.io-redis --save

最后,

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)
}