Right part of my code is
io.sockets.on('connection', function(socket){
var interval = setInterval(function() {
repaintGraph()
socket.emit('set data chart', '{"series":[['+series+']]}');
}, 1000 );
The chart in this case, if I have 3 users connected, the chart updates 3 times in one second I need to execute the code 1 time in 1 second, regardless of the number of clients
You can run the interval code outside of the connection code:
setInterval(function() {
repaintGraph();
io.emit('set data chart', '{"series":[['+series+']]}');
}, 1000);
io.on('connection', function() {
...
});
io.emit() will broadcast the message to all connected clients, every second.
There's a little bit of an inefficiency in the code, in that it will call repaintGraph() every second even if there aren't any clients connected, but it makes the code much easier.
try to use
socket.broadcast.emit('event',data)
Related
server.js
io.on('connection', function (socket) {
var addedUser = false;
socket.on('setTimer', function(data) {
timer.setEndTime(data.time);
socket.broadcast.emit('currentEndTime', {time: timer.getEndTime() });
});
});
client.js
$(function() {
var timer = new Timer(),
socket = io.connect('http://localhost:3000');
socket.on('currentEndTime', function (data) {
//this is the full date time in ms.
timer.setEndTimeFromServer(data.time);
});
set = setInterval(function(){
$('.time').trigger('click');
clearInterval(set);
},100);
$('.time').on('click', function(e) {
e.stopPropagation();
var time = $(this).text() * 1000;
timer.setEndTime(time);
timer.timeRemaining();
socket.emit('setTimer', { time: time });
});
});
Hi there, i am trying to integrate countdown timer for node js/socket io application. Timer works fine, but how do i avoid timer reset on new socket connection/page refresh. Thank You
This is because of two things:
Your socket goes away when you hit the refresh button and a new one is created and thus your connection to the server (and hence the timer value) goes away when you hit the refresh button.
When you load the page first, you don't get the current value of the timer and print it on your page to start everything.
You can have each individual timer stored in a key value storage. You can use the IP Address as key and timer value as value or something like that. This way, you can retrieve the current value of the timer for the user when user connects to the server and continue counting down.
If you use the socket ID as key, it will do you no good except to pointlessly populate a key value storage and spike up your memory usage. Use something more persistent, such as IP Address, username, e-mail or something of that sort as key and current value of timer as value.
Also, your current solution is flawed because it faces the "refresh lag". When you hit the refresh button, you stop counting for the amount of time that is spent on re-rendering of your web page. If it's nothing more than a handful of milliseconds, you're fine; but as long as it goes to a few hundreds of milliseconds, this will make actual difference. Do the count down at the server side. Just notify the client at the set intervals. This will increase the server workload, but at least you're not bound to having bad timers.
If you're going to have a single countdown, like "x days, x hours, x minutes, x seconds remaining to Superbowl or some other big event", you're much better off without socket.io. Just send the timestamp to the big event to the client and do the remainder on the client side.
So I'm developing simple game with the following scenario:
2 users need to start a game (so I'm creating new room for 3rd user and so on)
2 users is maximum per room
When game is started, event is sent to client, after 60 seconds server needs to end the game.
Code which I wrote will work only for 1 room, but for multiple rooms, cancelling is not correct because my lastRoom variable is incorrect.
I'm new to node.js so I'm not really sure how to deal with this.
Some code:
var lastRoom = 'default'; //this is the first created room
function tryToStartGame(socket){
var clients = io.sockets.adapter.rooms[lastRoom];
console.log("Size of room "+lastRoom+" is: "+getObjectSize(clients));
//we are checking size of last room
if (getObjectSize(clients) == 2){
//players in the room should be different
games['default']= {
'leftPlayer': getFromObject(clients, 0),
'rightPlayer': getFromObject(clients, 1),
'stuff': "some data here"
'roomName': lastRoom
};
console.log("We can start the game");
//let all the people in that room
io.to(lastRoom).emit('game', games['default']);
//game to cancel
gameToCancel = lastRoom;
//client needs to be aware when game is ended
//but if we have simultaneous games this will not work
setTimeout(function(){
console.log("Cancelling game in: "+gameToCancel);
io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");
}, 8000); //after 8 seconds for test
//reset the room name, so next time when this function is called in second room
//we will have something different
lastRoom = 'game'+new Date().getTime();
}
//we have less then 2 players, wait for another player
if (getObjectSize(clients)<2){
console.log("Less then 2 players");
socket.emit('waiting', 'Waiting for another user to join the game');
}
}
And tryToStartGame(socket) function is called always at connection like this:
io.on('connection', function(socket){
//when client says he wants to play
socket.on('joinGame', function(username){
//add user
addUser(socket, username);
//send list of players
io.emit('playersList', getFormatedPlayers());
//figure out in which room this player bellongs
socket.join(lastRoom);
//try to start the game
tryToStartGame(socket);
});
Problematic part is that lastRoom variable is overwritten and then setTimeout picks the wrong room, so what happens that basically last game is canceled, and the previous ones are not.
How should I correctly track and cancel the game in correct rooms ?
As you noted, lastRoom is a global variable and might/will change between the time you set it and the timeout
You can create a closure on the timeout function to keep the room as a locale variable:
var lastRoom = 'default'; //this has to be set in the same function than the call to setTimeout
//client needs to be aware when game is ended
//but if we have simultaneous games this will not work
setTimeout(function(){
var gameToCancel = lastRoom;
console.log("Cancelling game in: "+gameToCancel);
io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");
}, 8000); //after 8 seconds for test
I have a socketIO/express app that goes like this :
function joinRoom(socket,roomName){
socket.join(roomName);
console.log('success joining '+roomName);
socket.broadcast.to(roomName).emit('chat',{type:'join',msg:guestList[socket.id]+' has arrived in '+roomName+'!'});
socket.emit('chat',{type:'join',msg:'You are now in '+roomName});
}
function assignName(socket){
var name = 'Player#'+guestId;
guestList[socket.id]= name;
socket.emit('chat',{type:'name',msg:name});
return guestId+1;
}
io.sockets.on('connection', function (socket) {
io.of('/lobby').on('connection', function (socket) {
guestId=assignName(socket);
joinRoom(socket, 'Lobby');
});
handleMessage(socket);
});
When I open a first browser window, everything goes well, I see Player#0 connected, and the join room msg. However, when I open a second window or browser, I see 2 connections (player#1 and #2), then if I open a 3rd window, i will see 3 connections, #3,#4,#5. What the heck? It has to be something stupid but I can't figure it out, Help!
G.
Sorted!
Basically, I separated the namespace connection from the io.sockets.on(...) and behaviour went back to normal. It makes sense, although I'm not sure why the number of connect events was incremental...
to many this may be an easy question but I'm trying to figure out the reason/logistics as to how socketIO handles variables. In the following code, x is set to 0, every second it counts up. Now if you had 1000 clients connected, every time the connect would each client get a new count starting at 0 and not affect every other connected client?
Also, is there a way to emit a new number to ever connected client instead of each connected client? Thanks!
io.sockets.on('connection', function (socket) {
x= 0;
var socketSend = setInterval(function(){
x = x+1;
socket.emit('count', { number: x });
}, 1000);
});
the socketSend is visible only to inside the callback of connection event, so every time a client connects the callback is called, passing along the socket object, so every client will get 0 as a start and the count will begin.
I know socket.io has a built in feature for reconnecting and everything, however I don't think that it is working - as I have seen from others it's also not working for them either.
If a user puts their computer to sleep, it disconnects them, and then when they open it back up they are no longer connected so they don't any of the notifications or anything until they refresh the page. Perhaps it's just something that I'm not doing correctly?
var io = require('socket.io').listen(8080);
var users = {};
////////////////USER CONNECTED/////
console.log("Sever is now running");
io.sockets.on('connection', function (socket) {
//Tell the client that they are connected
socket.emit('connected');
//Once the users session is recieved
socket.on('session', function (session) {
//Add users to users variable
users[socket.id] = {userID:session, socketID:socket};
//When user disconnects
socket.on('disconnect', function () {
//socket.socket.connect();
var count= 0;
for(var key in users){
if(users[key].userID==session)++count;
if(count== 2) break;
}
if(count== 1){
socket.broadcast.emit('disconnect', { data : session});
}
//Remove users session id from users variable
delete users[socket.id];
});
socket.on('error', function (err) {
//socket.socket.connect();
});
socket.emit("connection") needs to be called when the user reconnects, or at least the events that happen in that event need to be called.
Also socket.socket.connect(); doesn't work, it returns with an error and it shuts the socket server down with an error of "connect doesn't exist".
The problem is related to io.connect params.
Look at this client code (it will try to reconnect forever, with max delay between attempts 3sec):
ioParams = {'reconnection limit': 3000, 'max reconnection attempts': Number.MAX_VALUE, 'connect timeout':7000}
socketAddress = null
socket = io.connect(socketAddress, ioParams)
There are two important parameters out there, related to your problem:
reconnection limit - limit the upper time of delay between reconnect attemts. Normally it's getting bigger and bigger in time of server outage
max reconnection attempts - how many times you want to try. Default is 10. In most cases this is the problem why the client stops trying.