send data from server to client on server event with socket.io - node.js

i can send data with a string tag on the server with
import io = require('socket.io');
var sio = io.listen(server);
sio.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
outside socket i can send a string only
sio.sockets.emit( "keystroke");
is there a way to make the data emitting possible outside on 'connecting' and not only a string.
i want to send json data on an event serverside with the same tag eg 'news'

Sure, you just have to save the socket that you want to send to or use a chatroom that you can broadcast to. Here's what it looks like if you save the socket:
import io = require('socket.io');
var sio = io.listen(server);
var client;
sio.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
client = socket;
});
// then, sometime later in response to some server-side event,
// you can send to that saved socket
client.emit("whatever", {yourData: someData, otherData: whatever});
Of course, you probably don't save the client socket in a variable the way it is shown here because you probably support many different clients. How exactly you should save it depends upon what you're trying to do. If multiple client want to register an interest in specific types of events, then the chat room capability built into socket.io can serve that purpose pretty nicely. Each client can request to join that chatroom with your own specific command, the server can put them in that chatroom and then, when the event occurs, you can just broadcast the data to the chatroom and it will be sent to all clients how have been put in the chatroom. Chatrooms are like saved lists of client sockets that the socket.io library manages for you.
If you had all the clients in the "events" chatrooom, then you can broadcast to all clients in that chatroom from the server like this:
io.to('events').emit("whateverMsg", {yourData: someData, otherData: whatever});

Related

Receive socket.io messages outside of connection

I know that messages can be sent outside the socket connection code block. How can I receive messages from the client the same way?
// Create socket.io server attached to current HTTP server
var io = require('socket.io')(server);
// When connection is made, set up some definitions for the server's connections
io.on('connection', (socket) => {
console.log('Local server connected...');
socket.on('disconnect', () => {
console.log('Local server disconnected...');
});
// I can receive messages here
socket.on('sendToRemote', function (data) {
console.log(data);
});
});
// Messages can be received outside the socket code using this syntax:
io.of('/').emit('runCamera', "Client connected...");
// I can't receive messages here...
// How can the server receive messages outside the socket code?
// I tried using the code below but it didn't work.
// Syntax compiles but doesn't work like the one above.
io.of('/').on('sendToRemote', function (data) {
console.log(data);
});
You need to have a socket to get messages from. You can emit to a room because it's tracking all the sockets connected to that room.
So to get messages only in a specific room:
io.of('/').on('connection', function (socket) {
socket.on("sendToRemote", function (data) {
console.log(data);
});
});

NodeJs Socket.io Rooms

This is a pretty simple question but i want to make sure that i am scaling our socket.io implementation correctly. We are using socket.io to respond back to the client after a lengthy process on the nodejs backend. So basically client makes call, then socket.io signals the client that the process has completed. Also socket.io ONLY responds to a temporary room that was established for the request.
In nodejs i created a global variable for the following so that i could emit back to the client room:
global.io = require('socket.io')(server);
But to create the room itself I am a little unsure how to create it globally such that only the socket that connected and made the request receives the response.
So if i have 500 client machines that initiate a connection through socket.io, each one will have its own socket. To ensure that the rooms are unique i use a guid across all 500. Of course i do not want all sockets to receive traffic if only one socket for a specific room is supposed to be evaluating the emit....
any ideas?
If I understood your question correctly, you're looking to send information to that 1 socket?
Perhaps something like this:
socket.broadcast.to(socketId).emit('someeventname', eventData);
If you have the connection open with that client, that means you have their socket id through socket.id . You can emit events to just that socket.
const app = express();
var http = require("http");
var server=http.createServer(app).listen(2525, (req, res) => {
console.log("Server running on", 2525);
});
var socketIO = require("socket.io");
var io = socketIO(server);
global.io = io
io.on("connection", async (socket) => {
socket.on("joinrooms", async (data) => {
socket.join(data.userId);
});
socket.on("sendMessage", async (data) => {
console.log("message", data);
io.to(data.touserId).emit("sendMessage", data);
});
});
/* Must Read section
Joinrrom data sample
data={
userId:123 //User's unique id.
}
sendMessage data sample
data={
userId:123, //sender User's unique id.
touserId:456, //reciver User's unique id.
}
Here I'm creating a room from the user's unique id(stored in DB) so whenever I
want to send data to a particular user I will emit an
event("io.to(data.touserId).emit") using the user's
a unique id that way only specific users will get messages.
*/

How to emit data from socket-IO client to socket-IO server?

so I am developing an small application that need a bi-directional channel to transmit data between client and server.
I have no problem to send sata from server to client. Works just fine. But , the other way around is not working. for some reason , sending data from client to client does not work.
here is the client.js
let io = require('socket.io-client');
let socket = io.connect("http://localhost:5000/", {
reconnection: false
});
socket.on('connect', function() {
console.log('Connected to server');
socket.emit('data', 'data is emitted !')
});
and here is server.js :
var io = require('socket.io').listen(process.env.port||5000);
io.on('connection',function () {
console.log('client connected');
io.on('data',function (data) {
console.log(`data received is '${data}'`)
})
});
What am I missing ?
The server code needs to listen for incoming events from a particular socket.on(), not io.on(). io is the server. It gets notified of new connections, but not of individual messages on a given connection. You have to listen to events on a particular socket to receive data from the client.
So, change to this (change io to socket in one place and add socket argument to the io.on('connection', function(socket) ()); handler (see the two places that socket was added below):
const io = require('socket.io').listen(process.env.port||5000);
io.on('connection', function(socket) {
console.log('client connected');
// listen for incoming data msg on this newly connected socket
socket.on('data',function (data) {
console.log(`data received is '${data}'`)
});
});
Note: the addition of socket in two places.

How do I connect two Socket.io servers/apps?

I'm trying to build an application that has two components. There's a public-facing component and an administrative component. Each component will be hosted on a different server, but the two will access the same database. I need to set up the administrative component to be able to send a message to the public-facing component to query the database and send the information to all the public clients.
What I can't figure out is how to set up a connection between the two components. I'm using the standard HTTP server setup provided by Socket.io.
In each server:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
And on each client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
I've looked at this question but couldn't really follow the answers provided, and I think the situation is somewhat different. I just need one of the servers to be able to send a message to the other server, and still send/receive messages to/from its own set of clients.
I'm brand new to Node (and thus, Socket), so some explanation would be incredibly helpful.
The easiest thing I could find to do is simply create a client connection between the servers using socket.io-client. In my situation, the admin server connects to the client server:
var client = require("socket.io-client");
var socket = client.connect("other_server_hostname");
Actions on the admin side can then send messages to the admin server, and the admin server can use this client connection to forward information to the client server.
On the client server, I created an on 'adminMessage' function and check for some other information to verify where the message came from like so:
io.sockets.on('connection', function (socket) {
socket.on('adminMessage', function (data) {
if(data.someIdentifyingData == "data") {
// DO STUFF
}
});
});
I had the same problem, but instead to use socket.io-client I decided to use a more simple approach (at least for me) using redis pub/sub, the result is pretty simple. My main problem with socket.io-client is that you'll need to know server hosts around you and connect to each one to send messages.
You can take a look at my solution here: https://github.com/alissonperez/scalable-socket-io-server
With this solution you can have how much process/servers you want (using auto-scaling solution), you just use redis as a way to forward your messages between your servers.

Sending a message to the client on connection using node and socket io

How do i send a message to a specific client, more specifically, the client that has just connected to the app without broadcasting to the rest of the visitors that are already on the site?
io.sockets.on('connection', function(client) {
});
Seems to broadcast to everyone every time a new visitors connects.
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('greetings', { greeting:'hello, new visitor' });
socket.on('greetingFromVisitor', function (data) {
console.log(data);
});
});

Resources