I am just trying to create a simple app using Socket.io. I am trying to send a notification (technically, emit an event) to all the connected users, if a particular user, User X, has disconnected, that User X has left or has disconnected.
Here is my server side code.
io.on('connection', function(socket){
console.log('Connected! ' + socket.id);
socket.on('disconnect', function(){
for(var i=0;i<onlineUsers.length;i++)
{
if(onlineUsers[i].socketId == socket.id)
{
var newMessage = {};
newMessage.socketId = onlineUsers[i].socketId;
newMessage.fullName = onlineUsers[i].fullName;
newMessage.message = newMessage.fullName + " IS DISCONNETED!";
io.emit('newMessage', newMessage);
onlineUsers.splice(i,1);
console.log('splicing id ' + socket.id);
}
}
}
I guess that the code is executing but takes long to emit the disconnection event. I receive the disconnection message about 2 minutes after the client had disconnected. Why does it take so long? What might be the wrong in this code?
I also cannot understand when exactly the client is considered as disconnected. If the app closes, or the browser closes or the internet goes down?
Thanks in advance.
Update: I have a test deployment on Cloud9 and my live deployment is on Azure Cloud. I have realized that Cloud9 works just perfect, this seems like an issue with Azure.
Update 2: Whenever I disconnect/close/refresh my web client, I immediately get the disconnected event emitted by the server. The same does not happen for my mobile client. Why?
Related
i am new to socket.io & nodejs. i have been writing a tictactoe game and i have a problem in it, my purpose is if someone refresh the page or close the browser let his/her opponent know . i know i should do this with disconnect event and here is what i try, but it is not working .
server side
socket.on('disconnect', function() {
socket.emit('user:disconnect');
});
client side
socket.on('user:disconnect', function() {
var message = player.getPlayerName() + ' leaves';
socket.emit('gameEnded', {room: this.getRoomId(), message: message,id:player.getPlayerId(),gameid: this.getGameId(),winType:"leave"});
});
also, i need to know how to get the room of disconnected user .
i already saw this but i just want to send the users in a room not all users in the whole application.
server.js
socket.on('disconnect', function() {
socket.emit('user:disconnect');
});
In the above code if a user named 'xxx' is disconnected, server is emitting 'user:disconnect' to the same user. You have to find the socket connection of other player and emit the event to that client.
You can achieve your goal by joining both the clients in a room and send message to other user in the room.
socket.join('room1');
io.sockets.in('room1').emit('user:disconnect');
Otherwise you have to store all clients as mentioned below and send message to the specific client using the following code.
var users = {
'client1': [socket object],
'client2': [socket object],
'client3': [socket object]
}
users['client3'].emit('user:disconnect')
I currently have a chat.
If the client connection is unstable and the socket connection is lost, the server will recognize it as socket.disconnect and delete the client from the chat room.
Then, when reconnecting, the client automatically exits the room.
How do I resolve this?
The idea is to create a setTimeout at disconnect to hold the client for 20 seconds to be deleted from the chat room, and then delete the setTimeout when reconnecting.
When doing this, how do you know that the client is reconnected?
Does socket.id change when reconnected?
If socket.id does not change because I created a user-specific array based on socket.id, I think we can solve this problem at the moment.
socket.on('reconnect', function() {
if( typeof event_timeout[socket.id] !== "undefined" )
clearTimeout(event_timeout[socket.id]);
}
socket.on('disconnect', function() {
event_timeout[socket.id] = setTimeout( exit_chat, 20000 );
}
I've seen many similar questions here, like this one about connecting servers to sockets, however, that doesn't seem to be working.
My goal is to have one of my server pages occasionally emit an "advance" event to all of the connected clients. My sockets server listener (sockets.js) looks like this
io.on('connection', function (socket) {
socket.on('advance', function () {
console.log('advancing clients');
io.emit('advance');
});
});
and my other server page (queue.js) has this code
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
I have also tried
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.emit('advance');
Both of those were in the other question I linked, however both of those failed. In the case of the first example, I received the error
socket.on is not a function
and on the second
socket.emit is not a function
it would seem that socket.connect worked, however, socket.on and socket.emit both failed. The idea is that queue.js will emit an event to all the clients, so they know to request the next song from the server.
As bonus points, I happen to be using passport.socketio to authenticate my users (though I don't seem to be getting the "ioAuthFail" message that would normally occur when a user attempts to connect and is not authenticated).
for what it's worth, my socket authentication code looks like
io.use(passportSocketIo.authorize({
//cookieParser:
key:'user',
secret:'secret',
store:new MongoStore({mongooseConnection:mongoose.connection}),
success:onAuthorizeSuccess,
fail:function(){console.log('ioAuthFail')}
}));
If there's a better way to advance the clients than using socket.io, i would also accept that, but for now it seems like this is the best way for me, assuming I can get this working.
EDIT
as mentioned through comments, changing my code to
var io = require('socket.io-client');
socket = io.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
socket.emit('advance');
doesn't break it, but it doesn't work, either.
Simple question, maybe simple answer: how do I know on the server that a certain client has disconnected? Basic use case: the serve would need to know if a player has dropped the connection.
In the publish function, you can watch socket close event as follows.
this.session.socket.on "close", -> # do your thing
Meteor.publish("yourPublishFunction", function()
{
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function()
{
console.log(id); // called once the user disconnects
}, function(e){console.log(e)}));
return YourCollection.find({});
});
I've created a pretty comprehensive package to keep track of all logged-in sessions from every user, as well as their IP addresses and activity:
https://github.com/mizzao/meteor-user-status
To watch for disconnects, you can just do the following, which catches both logouts and browser closes:
UserStatus.on "sessionLogout", (userId, sessionId) ->
console.log(userId + " with session " + sessionId + " logged out")
You can also check out the code and do something similar for yourself.
Maybe (in the server code)
Meteor.default_server.sessions.length
or
Meteor.default_server.stream_server.open_sockets.length
you can do one thing make a event on server and call it from browser with ajax which call after some small time interval settimeinterval using with session values into header and if server din`t get request from user it means he dropped connection
I'm making an application where I need to map sockets to some object. I thought I would be safe using the socket.id variable provided by Socket.IO. Unfortunately while debugging I found out that the socket.id changed without the client disconnecting/reconnecting or whatever.
Here's a small piece of code to show what I'm trying to do:
var io = require('socket.io').listen(8080),
var myVariable = new Array();
// Main event loop
io.sockets.on('connection', function (socket) {
socket.on('myEvent', function(data) {
myVariable[socket.id] = data;
}
// 'someOtherEvent' which uses the mapped data.
socket.on('someOtherEvent', function(data) {
// Doesn't always work because socket.id has changed and var is empty
doSomethingWith(myVariable[socket.id]);
}
});
I'm not sure but I don't think this is the desired effect. Why does this happen and how would I work around it?
I was using node-inspector to debug my application and because I was holding the code on some breakpoint it disconnected the client (probably some timeout client side). That's why I got a new socket.id when I continued the code execution.
Looks like 'someOtherEvent' emited before 'myEvent' or socket has been reconnected. I use socket.id as connection identifier on two different projects in production and it works without any problems.