Pass data from a Node.js server to a socket.io app - node.js

I have this very simple app:
// Require HTTP module (to start server) and Socket.IO
var http = require('http'),
io = require('socket.io'),
url = require('url');
var server = http.createServer(function(req, res){
req.on('data', function(data){
console.log('Received Data');
})
});
server.listen(3000);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
server.on('data',function(event){
client.send(url.search);
console.log('Received Data from socket app');
});
client.on('disconnect',function(){
console.log('Server has disconnected');
});
});
I need to curl the node server to pass it some post data, then i would like this data to be handed to the socket.io app so that it can feed back to the currently connected clients.
Is there anyway to accomplish that ?
Many thanks,

The socket that you get from
var socket = io.listen(server);
you can always call emit on this to send a message to all connected clients. So in your http server, you can emit the posted data:
var server = http.createServer(function(req, res){
var body = '';
req.on('data', function(data){
console.log('Received Data');
body += data;
});
req.on('end', function() {
// Emit the data to all clients
socket.emit('foo message', body);
});
});

Related

Why does not sending data io.sockets.emit and socket.broadcast.emit

Tried different methods, but the data is sent to a maximum of one or two clients. How to send data to all the clients connected to the server ? What am I doing wrong?
Server.js:
var PORT = 3000;
var options = {
// 'log level': 0
};
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server, options);
server.listen(PORT);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/attantions/templates/.default/template.php');
});
io.sockets.on('connection', function (client) {
client.on('attantion', function (data) {
try {
// Tried so
io.sockets.volatile.emit('attantion', data);
// And tried so
io.sockets.emit('attantion', data);
client.emit('attantion', data);
client.broadcast.emit('attantion', data );
} catch (e) {
console.log(e);
client.disconnect();
}
});
});
Client.js:
socket.emit("attantion", data);
socket.on('attantion', function (data) {
pushData(data);
});
See this post for different options for socket.io messages
Send response to all clients except sender (Socket.io)
io.sockets.on('connection', function (client) {
client.on('attantion', function (data) {
//client.emit('attantion', data ); // This will send it to only the client
//client.broadcast.emit('attantion', data); // This will send it to everyone but this client
io.emit('attantion', data); // This will send it to all attached sockets.
});
});
Edit
I wonder if this post can help you?
Socket.io - Cannot load file
I was curious how sending the php file to the client through node.js works? are you using another framework?
Could you show more of what your client code looks like? loading the lib and the instantiation of the socket.

How to emit message from client side [node.js + socket.io]

I am trying to emit message from client side with socket.io ...
Here is my client code:
var socket = io.connect('http://localhost/');
socket.on('connect', function(data){
setStatus('connected');
socket.emit('subscribe', {channel:'update.comment'});
});
Server:
io.sockets.on('connection', function (socket) {
socket.emit('message', { text : 'Welcome!' });
socket.on('subscribe', function (data) {
socket.join(data.channel);
redisClient.subscribe(data.channel);
});
});
Also I get this error message in console:
GET
http://localhost/socket.io?EIO=3&transport=polling&t=1442169984269-1
404 (Not Found)
Full serever:
var app = require('express')();
var http = require('http').Server(app);
var redis = require('ioredis');
var io = require('socket.io')(http);
redisClient = redis.createClient();
//look for connection errors and log
redisClient.on("error", function (err) {
console.log("error event - " + redisClient.host + ":" + redisClient.port + " - " + err);
});
io.sockets.on('connection', function (socket) {
socket.emit('message', { text : 'Welcome!' });
//on subscription request joins specified room
//later messages are broadcasted on the rooms
socket.on('subscribe', function (data) {
socket.join(data.channel);
redisClient.subscribe(data.channel);
});
});
redisClient.on('ready', function(data) {
console.log('#redis ready');
});
redisClient.on("message", function(channel, message){
console.log(channel);
var resp = {'text': message, 'channel':channel};
io.sockets.in(channel).emit('message', resp);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
New Problem Recognized:
Your server is listening on port 3000, but you are attempting to connect on port 80. The error message http://localhost/socket.io?EIO=3&transport=polling&t=1442169984269-1 has no port number on it so that defaults to port 80.
That error message means that your server-side socket.io code is not initialized correctly and thus is not listening for the HTTP request that starts all webSocket connections so when the browser tries to connect on that URL to initiate a socket.io connection, there's nobody on the server-side listening so the web server returns a 404 error back to the browser.
If you are using Express, this is the minimal socket.io initialization to hook it into your server:
var express = require('express');
var app = express();
var server = app.listen(8081);
var io = require('socket.io').listen(server);
For a plain HTTP server, this is the minimal socket.io initialization:
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
app.listen(80);
As always, if you show us the socket.io and web server initialization code you are using, we can help you better with your specific code issue.

How to emit event in socket.io based on client?

I am working on realtime data visualization application using node.js, express and socket.io.
Requirement:
Have to emit the events based on the client request.
For example: If user enter the url as http://localhost:8080/pages socket.io should emit the topic pages to client and another user request for http://localhost:8080/locations socket should emit location to that particular user.
Code
var server = app.listen("8080");
var socket = require('socket.io');
var io = socket.listen(server);
var config = {};
io.on('connection', function (socket) {
config.socket = io.sockets.socket(socket.id);
socket.on('disconnect', function () {
console.log('socket.io is disconnected');
});
});
app.get('/*', function(req, res) {
var url = req.url;
var eventName = url.substring('/'.length);
//pages and locations
config.socket.volatile.emit(eventName, result);
});
Client Code:
//No problem in client code.Its working correctly.
Sample code as follows
socket.on('pages', function (result) {
console.log(result);
});
Problem:
It is emitting pages and locations to both the clients.
Any suggestion to overcome this problem.
I couldn't understand your approach on this, but because you said you're rendering different pages, It means you can serve different code, so what about doing it like this:
Server Side:
var server = app.listen("8080");
var socket = require('socket.io');
var io = socket.listen(server);
var config = {};
app.get('/pages', function(req, res) {
res.render('pages.html');
});
app.get('/locations', function(req, res) {
res.render('locations.html');
});
io.on('connection', function (socket) {
socket.on('pagesEvent', function(data){
socket.volatile.emit('pages', {your: 'data'});
});
socket.on('locationsEvent', function(data){
socket.volatile.emit('locations', {your: 'data'});
});
});
On Client side:
pages.html:
socket.on('connect', function(){
socket.emit('pagesEvent', {});
});
socket.on('pages', function(data){
// do stuff here
});
locations.html:
socket.on('connect', function(){
socket.emit('locationsEvent', {});
});
socket.on('locations', function(data){
// do stuff here
});
You are doing it wrong, WebSockets supposed to work same in both directions. Client emit event to Server, server emit back to Client/Subscribers.
The way you are doing things, seems like a way of implementing API, but for some reason you are trying to implement it with WebSockets, instead of XHR.

Nodejs socket.io is emitting message to client as number of clients connected

I made a nodejs server wich uses socket.io to establish communication with web client, the server is sending sockets to specific client, the issue is if I have 5 clients connected to the server, the client will receive the sent message 5 times!
here is my code :
var fs = require('fs'),
http = require('http'),
io = require('socket.io'),
qs = require('querystring');
sys = require ('util'),
url = require('url');
var message, AndroidID;
//Traitement Serveur nodejs
var server = http.createServer(function(req, res) {
if(req.method=='POST') {
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end',function(){
server.emit('sendingData', body);
console.log("Body : " + body);
});
res.write("success");
res.end();
} else {
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
var socket = io.listen(server);
var clients = {};
var compteur = 0;
// Traitement socket.io
socket.on('connection', function (client) {
clients[compteur] = client;
client.emit('firstConnection', client.id, compteur);
console.log('clients : ', clients);
compteur += 1;
client.on('message', function (msg) {
console.log('Message Received: ', msg);
client.broadcast.emit('message', msg);
});
server.on('sendingData', function(data){
message = data.substring(8, data.lastIndexOf('&'));
androidID = data.substr(-1);
console.log('[+] Sending Data : ', message ,' TO : ', parseInt(androidID));
clients[parseInt(androidID)].emit('androidmsg', message);
});
});
The nodejs server is receiving data from a php HTTPClient
You should put server.on('sendingData', function(data){...}); outside socket.on('connection', function (client){...});. This is because the sendingData event is for http server and not socket.io server.
Putting it inside socket.io connection handler makes it repeatedly execute for each connected client to socket.io server

How to connect two node.js servers with websockets?

Here's my problem:
I have server A, running node.js and using socket.io for communicating with clients (web browsers). This all is running fine and dandy.
However, now that I have server B, which also needs to connect to server A through websockets, I have hit a wall. None of the node.js websocket clients I've found won't work with the socket.io on the server A.
So, this is the case I'm striving for:
.--------. .----------. .----------.
| CLIENT | <--> | SERVER A | <--> | SERVER B |
'--------' '----------' '----------'
Client-server A connection is done through socket.io
Now, Server B (running node.js) should connect to server A via websocket (in order to go through port 80). But...
Even the example code in socket.io-client module doesn't work... :/
// Connect to server
var socket = new io.Socket('localhost', {port: 8080});
socket.connect();
// Add a connect listener
socket.on('connect', function(socket) {
console.log('Connected.');
});
The code just passes without any errors and execution ends after few seconds.
Update: Code samples
Server (which works just fine) looks like this:
// Load requirements
var http = require('http'),
io = require('socket.io');
// Create server & socket
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(404, {'Content-Type': 'text/html'});
res.end('<h1>Aw, snap! 404</h1>');
});
server.listen(8080);
io = io.listen(server);
// Add a connect listener
io.sockets.on('connection', function(socket) {
console.log('Client connected.');
// Disconnect listener
socket.on('disconnect', function() {
console.log('Client disconnected.');
});
});
Client looks like this
console.log('1');
// Connect to server
var io = require('socket.io-client')
var socket = new io.Socket('localhost', {port: 8080});
socket.connect();
console.log('2');
// Add a connect listener
socket.on('connect', function(socket) {
console.log('Connected!');
});
console.log('3');
1, 2 and 3 prints out just fine, no errors, and few seconds later the process just exits
Also, server A doesn't output anything to the log, even though I have the socket.io logging set on "everything".
For future people:
Here is 2 very simple Node.js apps that use socket.io to connect, send and receive messages between each other.
Required package is:
npm install socket.io
Node-App-1 server.js:
var io = require('socket.io').listen(3000);
io.on('connection', function (socket) {
console.log('connected:', socket.client.id);
socket.on('serverEvent', function (data) {
console.log('new message from client:', data);
});
setInterval(function () {
socket.emit('clientEvent', Math.random());
console.log('message sent to the clients');
}, 3000);
});
Node-App-2 client.js:
var io = require('socket.io-client');
var socket = io.connect("http://localhost:3000/", {
reconnection: true
});
socket.on('connect', function () {
console.log('connected to localhost:3000');
socket.on('clientEvent', function (data) {
console.log('message from the server:', data);
socket.emit('serverEvent', "thanks server! for sending '" + data + "'");
});
});
Turns out I was using old examples, for some reason, even though I triple checked them. Well, doh.
Also, it turned out that the socket.io-client is broken on latest Node (6.x.x). Managed to find an update from github for it, replaced the files and yay, everything's working!
Edit: Unfortunately I didn't save any links to working examples but after quickly skimming through the code it seems that the only changes were to the client code, which now looks like this:
console.log('1');
// Connect to server
var io = require('socket.io-client')
var socket = io.connect('localhost:8080', {reconnect: true});
console.log('2');
// Add a connect listener
socket.on('connect', function(socket) {
console.log('Connected!');
});
console.log('3');
Here is a snippet of code I wrote, it's using socket.io 1.0.6 and socket.io-client 1.0.6. The case is the following:
Server A (Socket.io Client) <---> Server B (Socket.io Server)
Server B (Server):
// Load requirements
var http = require('http'),
io = require('socket.io');
// Create server & socket
var server = http.createServer(function(req, res)
{
// Send HTML headers and message
res.writeHead(404, {'Content-Type': 'text/html'});
res.end('<h1>Aw, snap! 404</h1>');
});
server.listen(8080);
io = io.listen(server);
// Add a connect listener
io.sockets.on('connection', function(socket)
{
console.log('Client connected.');
// Disconnect listener
socket.on('disconnect', function() {
console.log('Client disconnected.');
});
});
Server A (Client):
console.log('1');
// Connect to server
var io = require('socket.io-client');
var socket = io.connect('http://localhost:8080', {reconnect: true});
console.log('2');
// Add a connect listener
socket.on('connect', function(socket) {
console.log('Connected!');
});
console.log('3');
If I'm using localhost:8080 only on the client server it doesn't connect.

Resources