I am building a game using socketio.
The server stores the number of players, when it goes to 2, game start.
However, when I open two browser one by one, only the first one(not the latter one) receive the game start message.
Client side:
var socket = io.connect('http://localhost:8080');
socket.on('connected', function (data) {
$('#status').html('You are connected');
socket.emit('1 party connected');
});
socket.on('game start', function (data) {
$('#status').html('game start');
});
Server side:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8080);
var connected_parties_no = 0;
io.sockets.on('connection', function (socket) {
socket.emit('connected', { hello: 'world' });
socket.on('1 party connected', function () {
connected_parties_no++;
console.log(connected_parties_no.toString()+' parties are connecting.');
if (connected_parties_no == 2) {
game_start(socket);
}
});
socket.on('disconnect', function () {
connected_parties_no--;
});
});
function game_start(socket) {
socket.broadcast.emit('game start');
}
socket.broadcast.emit('game start');
will send the 'game start' event to everyone except `socket. You're most likely looking for
io.sockets.emit('game start');
Related
I'm totally new to the whole nodeJS asynchronous-y callback-y programming so I need more like a guidance to understanding what I'm even doing. With that said, I have two files main.js and server.js
My main file looks like this:
var server=require('./server.js');
server();
function WhenUserClicksButton(){
server();
}
and my server file looks like this:
var net = require('net');
function server(){
net.createServer(function (socket) {
socket.write('\x16'); //SYN character
socket.on('data', function (data) {
//handle data from client
});
}).listen(33333);
}
First call of server(); starts the TCP server. Then function WhenUserClicksButton is called when user clicks button (duhh) in a GUI. But it attempts to start the server again so I get
Error: listen EADDRINUSE :::33333
I got why this is happening but I can't think of a solution for it. What I really need is:
Start the server and listen on 33333
When nothing is happening server and client just exchanges SYN and ACK characters every few seconds (I already have this part done, I just removed it from this example for clarity because it's not really topic of this question)
When user click button change socket.write('\x16'); to socket.write('something');
Then wait for server and client to exchange data and after everything is done return results back to main.js
As I said, I'm new to this and I believe my problem lies in not understanding fully of what I'm doing. Any help and explanations are welcome!
I think you're very near where you need to be. I would do something like this:
server.js
var net = require('net');
var netServer = null;
var netSocket = null;
function sendData(data) {
if (netServer && netSocket) {
console.log('Send data: sending: ', data);
netSocket.write(data);
}
}
function startServer(){
netServer = net.createServer(function (socket) {
netSocket = socket;
socket.write('\x16'); //SYN character
socket.on('data', function (data) {
console.log('Server: data from client: ', data);
if (data.length === 1 && data[0] === 0x16) {
// log and ignore SYN chars..
console.log('SYN received from client');
} else if (newDataCallback) {
newDataCallback(data);
};
});
});
console.log('Server listening on 33333..');
netServer.listen(33333);
}
var newDataCallback = null;
function setNewDataCallback(callback) {
newDataCallback = callback;
}
module.exports = {
sendData: sendData,
startServer: startServer,
setNewDataCallback: setNewDataCallback
};
main.js
var server = require('./server');
function newDataCallback(data) {
console.log('newDataCallback: New data from server: ', data);
}
server.setNewDataCallback(newDataCallback);
server.startServer();
function wheneverUserClicksButton() {
server.sendData('something');
}
testClient.js
var clientSocket = net.createConnection(33333, "127.0.0.1");
clientSocket.on('data', (someData) => {
console.log('Data received', someData);
});
clientSocket.on('connect', () => {
console.log('Client Socket connected ');
clientSocket.write('Hello from client');
});
I'm new to node and socket io. I'm trying to implement a realtime notification system for couple of my own apps. So, using node, express and socket io, the code is given below:
Server Side Code:
io.on('connection', function (socket) {
socket.on('subscribe', function(room) {
socket.join(room);
});
socket.on('unsubscribe', function(room) {
socket.leave(room);
});
});
Client Side Code:
var sio = io.connect('http://localhost:9000');
var ch1 = sio.emit('subscribe', 'channel1');
ch1.on('log', function (data) {
console.log('channel1: ', data);
});
var ch2 = sio.emit('subscribe', 'channel2');
ch2.on('log', function (data) {
console.log('channel2: ', data);
});
I'm firing/emitting the event from a route (express) for example:
app.get('/', function(req, res) {
var data1 = {
channel: 'channel1',
evennt: 'log',
message: 'Hello from channel1...'
};
io.to(data1.channel).emit(data1.event, data1);
});
When I'm hitting the route, the io.to(data1.channel).emit(data1.event, data1); is working but it sending the data to both rooms/channels but I was expecting to get the data only in ch1 because data1.channel contains channel1 so I was expecting the following handler will receive the data:
ch1.on('log', function (data) {
console.log('channel1: ', data);
});
Notice that, both channels have same log event. Am I on the right track. Is it possible at all?
var ch1 = sio.emit('subscribe', 'channel1');
var ch2 = sio.emit('subscribe', 'channel2');
You're subscribing the same socket (sio) to both rooms. Also, ch1 and ch2 are references to sio.
If you want to test it properly, you should create a second socket for the second channel:
var sio2 = io.connect('http://localhost:9000');
var ch2 = sio2.emit('subscribe', 'channel2');
I have two applications A and B in Node Js and application B wants to communicate with application A.
Now Application A selects its port dynamically during run time. So how Application B can discover on which Port application A is running?
You can handle an event in app A and app B for ECONNREFUSED before starting your server in express which will take care of the port in used.if you see this error then just change the port number dynamically which will be true for both apps.
I did some more research and came up with solution which is "dns-discovery" and "openport"
First Check which port is open in your system using "openport" and then use "dns-discoverry".
Application A
var op = require('openport');
op.find(
{
startingPort: 8050,
endingPort: 8999
},
function (err, port) {
if (err) { console.log(err); return; }
console.log('opened port is:::::::::' + port);
ServerStart(port);
}
);
function ServerStart(port) {
var discovery = require('dns-discovery');
var disc = discovery();
disc.announce('connect-apps', port, function () {
console.log("announcement start")
});
var io = require('socket.io')(port);
io.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log("Response From Client::::::::::::" + msg);
socket.send("Congratulations from Server");
});
socket.on('disconnect', function (msg) {
console.log("We are disconnected");
});
})
}
Application B
var discovery = require('dns-discovery')
var disc = discovery()
disc.lookup('connect-apps', function () {
console.log('Server Lookup Started:::::::::::::::::::')
})
disc.on('peer', function (name, peer) {
console.log("Server found:::::::::" + peer.host + ':::' + peer.port);
var ws = 'ws://' + peer.host + ':' + peer.port;
var socket = require('socket.io-client')(ws, { forceNew: true });
socket.io.opts.transports = ['polling', 'websocket'];
socket.on('connect', function () {
console.log('connected');
socket.send('Hello from Client 1::::::::Vishal Shori Machine');
});
socket.on('message', function (msg) {
console.log("response again::::::::::::" + msg);
});
disc.destroy();
})
For Reference :
https://www.npmjs.com/package/openport
https://github.com/mafintosh/dns-discovery
I am using socket.io for private chatting for the server side I am using
socket.broadcast.to(receiver_socket_id).emit('message', data); // where data is a json object containing text
And at the client side code I catch the data using
socket.on('message', function (data) {
alert(data. text);
});
Its working properly and showing the alert on that specific user (socket id) ‘s panel when only two socket are connected (sender and receiver). But the problem appears when one more user connects to that socket then I see two alerts and when total 4 user connected (sender + receiver + two others) then see 3 alerts. But the good point is I can see the alerts only that specific client's panel not the others.
I can’t understand the problem, please help.
Please have a look on it
gyazo.com/a98d3a64a9fc6487e6ded8ccd90fd5ab
it prints test three times because three browsers are opened.
Full code here:
Sever side (I have used Redis):
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
server.listen(8080);
var usernames = {};
io.on('connection', function (socket) {
console.log(socket.id);
socket.on('adduser', function (userId) {
usernames[userId] = socket.id;
});
var redisClient = redis.createClient();
redisClient.subscribe('message-channel');
redisClient.on('message', function (channel, data) {
var jsonObj = JSON.parse(data);
var rcvrId = jsonObj.rcvrId;
socket.broadcast.to(usernames[rcvrId]).emit('message', data); // Not throwing error....should work
});
socket.on('disconnect', function () {
console.log(socket.id + ' Disconnected');
redisClient.quit();
});
});
Client side:
var socket = io.connect('http://localhost:8080');
var userId = $('input[name="userId"]').val();
var rcvrId = $('input[name="rcvrId"]').val();
socket.on('connect', function () {
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser', userId);
});
socket.on('message', function (data) {
data = jQuery.parseJSON(data);
console.log(data);
$("#messages").append("<div><strong>" + data.userId + " : </strong><span>" + data.message + "</span></div>");
});
You can use io.of('/').sockets[rcvrId].emit('message', data). In case you are using a different namespace just replace the / with your namespace.
-----------------------------client socket ----------------------
$(document).ready(function () {
var socket = io.connect('http://localhost:8282');
$('#stopbtn').click(function(){
socket.emit('RandomStatus',{message:'stop'});
})
$('#startbtn').click(function(){
socket.emit('RandomStatus',{message:'start'});
})
});
----------------------------------Nodejs server --------------------
var io = require('socket.io').listen(app.listen(8282));
io.set('log level', 1);
var randomizerjson = require('./randomizerjson');
io.sockets.on('connection', function (socket) {
var intervalId;
socket.on('RandomStatus', function (data) {
var status = data.message;
if(status=='start'){
//random data after 700 milisecond and send
intervalId= setInterval(function () {
var randomData = randomizerjson.getRandomData1();
//send random data somewhere
io.sockets.emit('dataSet', randomData);
}, 700);
}
if(status=='stop'){
clearInterval(intervalId);
}
});
socket.on('disconnect', function () {
console.log('user disconnect');
});
});
When I click start button, I can send random data. But when I click stop button, I can not clearInterval to stop sending random data.
I want to stop sending random data when I receive 'stop' message, but that's not working. Can anyone help me and tell me why?