[英]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.