I have a solution where an application is emitting messages using socket.io-emitter and a socket server is handling the messages.
The socket server receives messages from the client browser without an issue however it does not pickup any messages from the other application which are sent over the redis adapter.
I've debugged the redis adapter and can see that the messages are being received and I can also see that they are associated with the correct namespace. They just appear to not be firing the socket.on() event
The server code has more going on however basically boils down to the following
io.adapter(redisIO({host: redisHost, port: redisPort}));
io.of('/mynamespace').on('connection',
function(socket) {
// This message never gets fired
socket.on('other-server-message',dosomething);
// This message works fine
socket.on('message-from-browser-client',dosomethingelse);
}
);
There isn't much documentation around so any help would be great
I eventually realised what the issue was. I was misunderstanding what the socket.io-emitter was doing.
I was sending a message from the emitter and then trying to capture it on the server and then push it out to the clients. The emitter is actually broadcasting directly to the clients in the web browser as if it was just another server socket (which is what I wanted).
Soon as i updated the client code to check for the message it worked perfectly
Related
I'm developing a simple website, where the client and server communicate over web sockets. I'm using nodejs and the socket.io library for the socket communication
Specifically, my server works as a middleware between an mqtt broker and my client. So on one hand, my server connects with the mqtt broker to consume messages and on the other hand delivers these messages to the connected clients over web sockets. I'm using the node mqtt library for the mqtt communication.
My codebase is fairly large, so to give you a feeling of how my code looks like, I will show this example, which should be straightforward to understand:
const io = require("socket.io")(port);
handleRequests(io) {
io.on("connection", (socket) => {
logger.info(`New client connected: ${socket.id}`);
this.clients[socket.id] = { // track clients and subscribed topics
topic: '',
};
this.numberOfUsers++;
io.sockets.emit("onUser", this.numberOfUsers);
this.handleChange(socket);
this.addToSubscribedClients(socket);
this.removeFromSubscribedClients(socket);
this.handleDisconnect(socket);
this.sendMqttMessageToClient(socket);
});
}
This is my "main" function, where as you can see, I'm initializing an io object and using it later by passing it to the handleRequests function. Each time a new client connects, I'm calling the callback function where I call the five other functions and passing the socket object as a parameter, which should be fine I guess. I'm passing the socket object as a parameter because I need it to later call socket.emit in order to send back message to a specific client, since the socket object is unique for each client.
This works great until more than ~ 30 clients are connected. I'm trying to debug this for 2 weeks now and can't figure out why this is happening. I'm testing this by opening multiple tabs in my browser. I start with one client and then increase the number of clients/tabs. At some points, I notice that some clients receive no values from the server but other clients still do, which is incorrect since all clients should receive the values in real time.
I noticed that the clients, which are not receiving values have other ids than the ones stored on the server. I tested this with a simple console.log() on both clients and server. How this is happening? I'm very positive that I'm sending the ids correctly since there are other clients, which still receive values from the server. My guess is that the server is somehow disconnecting some clients automatically, because if a client reconnects then a new id will be assigned to it automatically.
Does anyone have any idea why this is happening? and why it works fine with the first ~30 clients and starts to occur when many clients are connected? This issue is very hard to debug since the code works fine for a small number of clients and no errors are thrown when the bug occurs, so I'm hoping that someone had this before.
Edit
Now I just found that i can print a reason for socket disconnection. When I do that, ping timeout is printed, which I don't understand because when I have one single or few clients connected then this error does not happen.
Node create a unique url and bind socket.io to it.
var io = require("socket.io").listen(server, {path: req.originalUrl});
When a client connects also binds his socket.io-client to that url
var socket = io('192.168.1.101:3000', {path: window.location.pathname});
I don't have problems and everything works great.
When a client performs a particular action, server do
socket.broadcast.emit("foo"); //I made console.log here and it prints
client-side:
socket.on("foo", () => console.log("okay"));
The problem is that client-side "foo" event is almost never fired. Sometimes it is fired but only in particular occations. For example it happened that a socket.io-client auto-reconnect to server and then the event is fired.
I don't know if the problem is related to this, because for example socket.emit works, but when another client connects I always get this
error
socket.broadcast.emit("foo");
broadcasts a message to all connected clients EXCEPT the one specified by socket. If you want to broadcast to all connected clients, then use:
io.broadcast.emit("foo");
You will also have to make sure that your clients are correctly connected and not regularly losing and re-establishing their connections (you can see if that is happening by logging the connection and disconnection events on the server). If they are losing their connections somehow and then reconnecting, then which ones would get the broadcast message would happen to depend upon which ones were not in the middle of a temporarily lost connection.
I have a web based multiplayer game. It happens from time to time that someone is kicked out because server did not get expected message from client. It seems from my logs that client did not disconnect, just did not send message or server did not receive it. My question here is "Does this things happen normally from time to time?" Should i use some kind of callback mechanism to ensure message is delivered and if not send it again or is there some issue that i am not aware?
socket.io already provides ACKs and message ID tracking, on top of TCP.
Also, socket.io uses pings to check the connection. So, if you say that the client is not disconnected, and the server tells that the client is not disconnected, then the connection is still there.
The problem must be situated elsewhere.
Are you sure there is not a bug in either part of the implementation? Showing some code snippets could help, as well as the environment you are using.
I'm creating a browser chat from Socket.io and Node.js. Everything has been running smoothly, but I appear to be having a problem with disconnecting sockets. When I run socket.disconnet();, the server runs the socket.on("disconnect", event, but it doesn't actually remove the socket from internal listeners.
When I run socket.disconnect(); on a socket, the socket no longer recieves any new messages, but when the "disconnected" user sends a message, the server receives and sends it back to all clients. I want to create a proper /kick command but it's difficult when I have to restructure all of my code just to accomidate for a simple function.
Commands like socket.connection.destroy();, socket.end();, and socket.transport.destroy(); are invalid and undefined. Does anyone have any suggestions? I've been working on this problem for days and I haven't found any answer other than to set a shutup boolean to the socket and tell the message event to ignore specific sockets. Is this the best way? What happens if the user starts editing javascript code and I need a way from receiving other events from a client?
Well you can see if the socket is connected or not. If socket is connected you can emit the data and vice versa. :)
Hope it helps..!
YourProject.sockets.on('connection',function(socket){
setInterval(function(){
if(!socket.disconnected){
socket.emit('entrance',{message:'Hey Bro'});
}
},10000);
});
have you tried to interrupt thread ? That should end all I/O operations with an Exception.
On the socket io server I have something like:
io.sockets.on('connection',function(client) {
console.log(client.id + ' connected at '+(new Date()).getTime());
client.on('disconnect',function() {
console.log(client.id + ' DISCONNECTED at '+(new Date()).getTime());
});
});
And my problem is that this happens:
debug - client authorized
info - handshake authorized 15229479751557595508
debug - setting request GET /socket.io/1/websocket/15229479751557595508
debug - set heartbeat interval for client 15229479751557595508
debug - client authorized for
debug - websocket writing 1::
15229479751557595508 connected at 1313769716321
debug - websocket received data packet 5:::{"name":"estimatepp","args":[9]}
debug - websocket received data packet 5:::{"name":"ready","args":[null]}
info - transport end
debug - set close timeout for client 15229479751557595508
debug - cleared close timeout for client 15229479751557595508
debug - cleared heartbeat interval for client 15229479751557595508
15229479751557595508 DISCONNECTED at 1313769716454
debug - discarding transport
I don't know if this is normal but as you can see, the client 15229479751557595508 connects at 1313769716321 and disconnects at 1313769716454, just 133 mili-seconds later (this number is always either 132 or 133). I'm not ordering the client to disconnect after something.
Any ideas on why does this happen ?
Also I have another doubt. If I listen for connection events on io.sockets.on, shouldn't I be listening for disconnect events also there ? Except there's no client there...
What is the correct way to listen for disconnections ?
Thanks for any help.
EDIT: You can ignore the lines
debug - websocket received data packet 5:::{"name":"estimatepp","args":[9]}
debug - websocket received data packet 5:::{"name":"ready","args":[null]}
It's part of the project I'm working on. Maybe the thing is that it just receives those events and after that because there's no activity for a while it closes the connection ? But this is not wanted behavior is it ?
The server-side code that you have posted is fine and should work as expected. Check for bugs in your client-side code (or post your client-side code here). If nothing there, try a different browser.
Regarding your disconnect event.
You have an io.sockets.on("connection", function (client) { ... }) event handler where when a new connection is made, a session is created for the connection and is stored in the client variable.
You then attach event handlers (like the disconnect one) to this client object.
Now when that client disconnects, the disconnect event handler attached to that particular client object is invoked.
Moreover, as you can see in Exposed Events — Socket.io, io.sockets.on only exposes the connection event.
I have similar thoughts as the creator of the question.
The time in ms is probably your roundtrip time to the server or the time it takes to manage connects with the client etc etc. So I wouldnt bother so much with the time factor.
I get same result when I refresh the client manually and repeatedly. between say half and one second intervals. This seems to create a scenario which otherwise only happen with poor network quality.
I can see in the logs that I get a connection, before a disconnection with the same socket.id.
client connected: qEcxQQCivSyKJVbF85dc
client disconnected: qEcxQQCivSyKJVbF85dc
However my on.disconnect event does in this scenario NOT fire.
On disconnects I clean up my local object of connected clients and I can see that I a client left in there and when I analyze the socket.connected status it is disconnected.
So under certain circumstances the above scenario causes a disconnect event to not fire.
Probably due to timings, asynch, network quality etc.
Two ways to go.
Build the application according to those constraints or
find someone who can come up with a more solid method for listening to on.disconnect, which, as the original question eluded, does not involve being attached to a specific socket client.
It is like the event listener is overwritten when the client connects again with the same id. A more general disconnect event listener would disregard that but potentially cause other issues instead.
I am personally going with option 1. and instead creating a garbage collector of sorts that clean up my local array of clients if they are disconnected.