Lets say..I have a two clients connected.
https://i.stack.imgur.com/90IlV.png
So as soon as i refresh any one of the browser both clients get disconnected..
https://i.stack.imgur.com/oZx99.png
and I have written code to remove socket if of the user that gets disconnected.
let userId = socket.request._query['userId'];
socket.on('disconnect', function(){
console.log("disconnect: ", socket.id);
User.removeSocketId(userId, (err, res) => {
if(err) throw err;
//updated code and found this emit was causing the issue, without this code everything work fine.
socket.broadcast.emit('chat-list-response',{
error : false ,
userDisconnected : true ,
socketId : socket.id
});
});
});
So because of this socket ID of both clients gets removed.
Is there any way to stop that multiple disconnection ??
Thanks in advance.
Related
I am utilizing socket.io V3.1.1 and am trying to figure out how to get the client to reconnect after the connection is disconnected due to a phone going asleep. When I run the code, it connects, refreshes an order, and then I press the power button on the iPhone to cause it to sleep. I then press the home key, and I see a disconnect event, followed by a connect event which refreshes the order. If I repeat the process, I see it disconnect, but I never see a connect event.
The question is, how does one reliably connect/reconnect and/or why don't I get additional connect events?
Here's a sample console.log output:
connect
refreshOrder 1234
disconnect due to transport error
connect
refreshOrder 1234
disconnect due to transport error
and then no more events
Here's the primary code that's involved:
const socket = io("wss://xyz.org:3000");
socket.on('connect', () => {
console.log("connect");
if (order_id !== null){
refreshOrder(order_id);
}
});
socket.on("disconnect", (reason) => {
console.log("disconnect due to " + reason);
socket.connect();
});
I also have the following event handlers, but they never get called:
socket.on('reconnect', () => {
console.log('reconnect');
if (order_id !== null){
refreshOrder(order_id);
}
});
socket.on("connect_error", (err) => {
console.log("connect_error: " + err);
setTimeout(() => {
console.log("socket.connect retry");
socket.connect();
}, 1000);
});
The answer is that you should ignore the disconnect and let the built-in reconnect code handle it. I believe that my problem was that I had looked at examples of pre-V3 code and didn't understand that it was handled differently in V3. So, a better disconnect event handler would be
socket.on("disconnect", (reason) => {
console_log("disconnect due to " + reason);
if (reason === "io server disconnect") {
// disconnect initiated by server. Manually reconnect
socket.connect();
}
});
we have this socket.io serverside that on auth joins the user in the rooms he is in, but on disconnect it seems like it does not really disconnect, because on a new connect i get 2 connections, seen in screenshot. Also included is the disconnect code part.
connection part:
io.on("connection", function(socket) {
console.log("connected");
console.log("user connected with " + socket.id);
disconnect part:
socket.on("disconnect", function() {
socket.removeAllListeners();
if (socket.auth) {
socket.groups.forEach(group => {
console.log("left " + group.chatGroupID);
socket.leave(group.chatGroupID);
});
}
delete socket[socket.id];
socket.disconnect(true);
console.log(socket.disconnected);
console.info("disconnected user (id=" + socket.id + ").");
});
server printout:
somehow i globbed all files in my folder sockets and thus nested my sockets which caused this weird behavior
I'm starting to work with Socket.io and my nodeJS API
I succeeded to get my user connected, and showed a message on my server.
But now, I'm trying to send data to my client -> then server -> then client again etc.
But when I use emit nothing appends... So this i my code :
SERVER SIDE
io.on('connection', function(socket){
console.log("user connected") // I see that
socket.emit('text', 'it works!'); //
socket.on('test1', function (data) {
console.log('received 1 : '); // Never showed
console.log(data); // Never showed
});
}
CLIENT SIDE
var socket = io.connect(myUrl); // good connection
socket.emit ('test1', {map: 4, coords: '0.0'}); // never showed on the server side
socket.on('text', function(text) {
alert(text); // never showed
socket.emit('test', { "test": "test2" });
});
Any ideas?
thanks !
Your Starter Code seems to be valid, you need to check two things :
if you successfully included the socket.min.js in the client side
if you re having any error printed in the console
On the client side, you have to wait until the connection succeeds before it is safe to send data to the server. Connecting to the server is not synchronous or instantaneous (thus it is not ready immediately). You are trying to send data before the connection is ready.
Put your first send of data inside a socket.on('connect', ...) handler.
var socket = io.connect(myUrl); // good connection
// send some data as soon as we are connected
socket.on('connect', function() {
socket.emit ('test1', {map: 4, coords: '0.0'});
});
socket.on('text', function(text) {
alert(text); // never showed
socket.emit('test', { "test": "test2" });
});
this worked for me
CLIENT SIDE
//sending custom data to server after successful connection
socket.on('connect', function(){
this.socket.emit('client-to-server', {map: 4, coords: '0.0'});
});
//listening the event fired by the socket server
socket.on('server-to-client', function(dataSendbyTheServer){
// do whatever you want
console.log(dataSendbyTheServer);
});
SERVER SIDE
io.on('connection', function(socket) {
// listening the event fired by the client
socket.on('client-to-server', function (data) {
console.log('received 1 : ');
// sending back to client
io.emit('server-to-client', data)
});
});
How do I get other user's socket.id?
Since socket.id is keep changing, whenever the browser refresh or disconnect then connect again.
For example this line of code will solve my problem
socket.broadcast.to(id).emit('my message', msg);
But the question is How do i get that id?
Let say Jack wants to send a message to Jonah
Jack would use the above code to send the message, but how to get Jonah's socket id?
Just for the record, I already implemented socket.io and passport library so that I could use session in socket.io , the library is call passport-socket.io. So to get the user id in socket.io would be
socket.request.user._id
What i did for this was to maintain a database model(i was using mongoose) containing userId and socketId of connected users. You could even do this with a global array. From client side on socket connect, emit an event along with userId
socket.on('connect', function() {
socket.emit('connected', userName); //userName is unique
})
On server side,
var Connect = require('mongoose').model('connect');; /* connect is mongoose model i used to store currently connected users info*/
socket.on('connected', function(user) { // add user data on connection
var c=new Connect({
socketId : socket.id,
client : user
})
c.save(function (err, data) {
if (err) console.log(err);
});
})
socket.on('disconnect', function() { //remove user data from model when a socket disconnects
Connect.findOne({socketId : socket.id}).remove().exec();
})
This way always have connected user info(currently used socketId) stored. Whenever you need to get a users current socketId fetch it as
Connect.findOne({client : userNameOfUserToFind}).exec(function(err,res) {
if(res!=null)
io.to(res.socketId).emit('my message', msg);
})
I used mongoose here but you could instead even use an array here and use filters to fetch socketId of a user from the array.
The documentation suggests that `socket.on(SOME_MESSAGE's callback is provided an id as the fist param.
http://socket.io/docs/rooms-and-namespaces/#default-room
javascript
io.on('connection', function(socket){
socket.on('say to someone', function(id, msg){
socket.broadcast.to(id).emit('my message', msg);
});
});
I tried to add new socket to some rooms in a middleware, but it seems not working while a first emit haven't be done for a socket(client side). When a socket (client side) send a 'message' event it will then work and be part of the room.
Is it a normal behavior?
Am I mandatory to join room in 'connection' event?
app.js (server side)
var app = require('http').createServer(function (req, res){
res.end('no rest');
});
var io = require('socket.io')(app);
app.listen(7076);
io.use(function(socket, next){
socket.join('toto');
next();
});
io.on('connection', function (socket) {
socket.on('message', function (data) {
socket.to('toto').emit('message', data);
});
});
According to the documentation, socket.to('toto').emit... syntax is not correct. You should use one of the following forms:
send everyone in "toto" room:
io.to('toto').emit('message', data);
send everyone in "toto" room except the sender:
socket.broadcast.to('toto').emit('message', data);
In fact the problem wasn't on the server side at all... It was my client that i didn't describe.
When clicked on a button to send a message here is the function called
function messageManagement(cb)
{
var message = $('#message_text').val();
if (!message || message.length == 0)
message = 'I am watching you';
socketClient.emit('message', {message:message});
socketClient.on('message', function (data){
console.log(data.messsage);
drawMessage(data);
});
}
As you can see each time the client emit a message it also register to the response event. So each time I emit a message a registered one more time to same event... It was messy so i changed this and it worked..