Node JS push server send/receive - javascript

I am trying to set up a node js server to do push notifications to my browser app. I have a basic example working, but I am wondering how to send data up to the server from the client on handshake.
I Need to send to the server something like a user id, so when a notification comes in for them, it can be routed back to the user.
my server looks something like this
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs');
app.listen(8000);
function handler ( req, res ) {
res.writeHead( 200 );
res.end('node working');
};
io.sockets.on( 'connection', function ( socket ) {
socket.volatile.emit( 'notification' , "blah" );
});
and my client looks something like this
var socket = io.connect('http://localhost:8000');
socket.on('notification', function (data) {
//prints data here
});

In socket.io, the emit is essentially like any other event handler (e.g. jQuery's .on('click'...)); you declare the event and send the data. On the server, you add the .on('event', ...) to catch the request and process it.
The socket.io front page shows this example for the server:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
And this for the 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>
It sounds like the part you're looking for is the socket.emit portion.

I have done this sort of thing in the past by setting a cookie on the client (which you're probably doing anyway), and then using socket.io's authorization event. You can use this event to decide whether to even accept the socket connection to the user in the first place.
io.configure(function () {
io.set('authorization', function (handshakeData, callback) {
var cookie = handshakeData.headers.cookie;
// parse the cookie to get user data...
// second argument to the callback decides whether to authorize the client
callback(null, true);
});
});
See more documentation here: https://github.com/LearnBoost/socket.io/wiki/Authorizing
Note that handshakeData.headers.cookie is just a string literal representation of the cookie, so you'll have to do your own parsing.

Related

Page doesn't automatically update when socket.io receive

I want to page update when new socket.io data appear.
I have a server -> client comunication:
Server code (the n var is the message)
io2.on('connection', function(socket2) {
socket2.on('live', function(data2) {
console.log('status from live client:', data2);
socket2.emit('live', n);
});
});
Live page code:
var socket = io.connect('http://localhost:3002');
socket.emit('live', 'live client is connected');
socket.on('live', function(data) {
//alert(data)
document.getElementById("demo").innerHTML = data;
});
The socket works fine because when I send the data and I refresh the page it show what I want. The problem is that I want to see the updated message without manual refresh.
Thanks!
The scope for n is undefined in the first function, so the receiving function doesn't have anything to show.
You'll need to define n in the original emitting function.
You need to emit the event from server side to the client side and then catch data there
var server = app.listen(3000);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
socket.on('event', function(data) {
var n = data.message;
io.sockets.emit('event', message);
});
And then on frontend in live page you write this
var n = <%-JSON.stringify(v1)%>;
var socket = io.connect('http://localhost:3000');
socket.on('event', (data)=>{
console.log(data)
});

How to send data to specific client in a specific room with socket io

My question is what's the proper way of sending data to a specific client in a specific room. I'm using socket io and the code written below:
I use the command:
socket.to(socket.id).emit('change', {data})
but the client never gets this command. Anyone know why?
Below is a snippet of my code:
server code:
io.on('connection', function (socket) {
socket.on('channelJoin', function(channel){
socket.join(channel);
if(deltasByChannel[channel])
{
console.log("sending initial data to: "+socket.id);
socket.to(socket.id).emmit('change', deltasByChannel[channel]);
}
socket.on("change", function(delta){
console.log("channel: " + channel+" was edited!");
console.log(deltasByChannel[channel]);
deltasByChannel[channel] ? deltasByChannel[channel] = deltasByChannel[channel].concat(delta) : deltasByChannel[channel] = delta;
socket.broadcast.to(channel).emit('change', delta);
});
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
client code:
var channel = window.location.pathname;
var socket = io.connect();
//Ace handlers
var sendUpdateData = function(e){
socket.emit("change", [e.data]);
};
socket.on('connect', function(){
socket.on("change", function(data){
console.log("change event received!");
editor.getSession().removeListener('change', sendUpdateData);
editor.getSession().getDocument().applyDeltas(data);
editor.getSession().on('change', sendUpdateData);
});
editor.getSession().on('change', sendUpdateData);
socket.emit('channelJoin', channel);
});
just to avoid confusion the editor object is listening for a change event as well. It's from an entirely different library (ace.js) that has nothing to do with my socket io issue.
below is another snippet of the server code for more clarity:
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000, function () {
console.log('listening on *:3000');
});
I think there's some confusion about sending data over sockets using socket.io. You can elect to emit events or data using rooms or private namesspaces, you can broadcast to all connected sockets, or you can emit data to a specific ID.
In your case you should just be selecting a socket.id, to emit an event to a particular connection. You can do this by:
io.sockets.connected[ socket.id ].emit('privateMsg', 'hello this is a private msg');
You can also use the to() method in conjunction with broadcast as well:
socket.broadcast.to( socket.id ).emit('privateMsg', 'hello this is a private msg');
This will reach the user which matches the socket.id you pass in as the argument.
To contact users within a "room" or private namespace, you can also use the to() method:
io.to('some room').emit('some event');
In this case some room would be the channel var you've defined, and it should match a predefined variable that has already been instantiated.
For more information about rooms/namespaces/and reaching specific socket connections: http://socket.io/docs/rooms-and-namespaces/#

Socket.IO not using fallback methods

I have a node server that's running a socket.io server and a client to work with it. Simple story, I need to be able to transfer messages between the two. This is working as intended in browsers that support web sockets but when a fallback method needs to be used its not working.
I should mention that pages are served from an apache server and the node server is only used for a specific page. The code that I am using is below, I've tinkered on this for a while and can't figure out how to fix it.
Also worth mentioning that when the page is opened in IE9(websockets not supported),
logging connection.io.engine.transport.name would give "websocket".
Client:
connection = io(window.location.protocol + '//localhost:8888', {
'reconnect': false,
'max reconnection attempts': 0,
'transports':
[
'websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling'
]
});
connection.on('connect',function () {
console.log("Socket is open");
$('#dc-status').hide();
connection.emit('message',JSON.stringify(info));
connection.on('message',function (e) {
//DO SOMETHING WITH THE DATA RECIEVED
});
});
Server:
var ioserver = require('socket.io');
var io = ioserver.listen(8888);
var http = require("http");
console.log("server started...");
io.set('transports',[
'websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling'
]);
io.sockets.on('connection', function(ws) {
var req;
var order;
var courier;
var after;
var session;
var options = {};
console.log("New client connected");
// console.log("Transport: " + io.transports[ws.id].name);
ws.on('message', function(data) {
//WORK WITH THE DATA RECEIVED
//NOT RELEVANT TO EXAMPLE
console.log('received: %s', data);
parsedData = JSON.parse(data);
});
ws.on('disconnect', function () {
console.log("Connection closed");
});
});
Ok, so after much struggle with this I have found a solution for making sockets work in old browsers.
As of version 1.0 Socket.io uses Engine.io instead of fallback methods, which takes care of transports.
To get a working solution I skipped using the Socket.io layer and used just Engine.io instead.
In the client you have something like
var connection = eio.Socket('host-address');
and then you just bind the regular events(e.g message, close).
And in the server part instead of require('Socket.IO'), you call require('Engine.IO'), example:
var engineio = require('engine.io');
var wss = engineio.listen(10101);
The binding is the same.

JavaScript callbacks function object

i try to learn node.js and try to create a new TCP Server connection. The code
var server = require('net').createServer(function(socket) {
console.log('new connection');
socket.setEncoding('utf8');
socket.write("Hello! You can start typing. Type 'quit' to exit.\n");
socket.on('data', function(data) {
console.log('got:', data.toString());
if (data.trim().toLowerCase() === 'quit') {
socket.write('Bye bye!');
return socket.end();
}
socket.write(data);
});
socket.on('end', function() {
console.log('Client connection ended');
});
}).listen(4001);
look at the callback function, after then, they call listen method. What is this for kind of object.
What it basically says is:
function myHandler(socket) {
// everything up to socket.on('end')
}
var server = require('net').createServer(myHandler);
server.listen(4001);
So it's just creating a socket server with a handler function, and then make the server listen to port 4001.

how to get session id of socket.io client in Client

I want to get session id of client in my socket.io client.
here is my socket.io client :
var socket = new io.Socket(config.host, {port: config.port, rememberTransport: false});
// when connected, clear out display
socket.on('connect',function() {
console.log('dummy user connected');
});
socket.on('disconnect',function() {
console.log('disconnected');
});
socket.connect();
return socket;
I want to get session id of this client , how can i get that ?
Have a look at my primer on exactly this topic.
UPDATE:
var sio = require('socket.io'),
app = require('express').createServer();
app.listen(8080);
sio = sio.listen(app);
sio.on('connection', function (client) {
console.log('client connected');
// send the clients id to the client itself.
client.send(client.id);
client.on('disconnect', function () {
console.log('client disconnected');
});
});
On socket.io >=1.0, after the connect event has triggered:
var socket = io('localhost');
var id = socket.io.engine.id
I just had the same problem/question and solved it like this (only client code):
var io = io.connect('localhost');
io.on('connect', function () {
console.log(this.socket.sessionid);
});
* Please Note: as of v0.9 the set and get API has been deprecated *
The following code should only be used for version socket.io < 0.9
See: http://socket.io/docs/migrating-from-0-9/
It can be done through the handshake/authorization mechanism.
var cookie = require('cookie');
io.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
data.cookie = cookie.parse(data.headers.cookie);
// note that you will need to use the same key to grad the
// session id, as you specified in the Express setup.
data.sessionID = data.cookie['express.sid'];
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
All the attributes, that are assigned to the data object are now accessible through the handshake attribute of the socket.io connection object.
io.sockets.on('connection', function (socket) {
console.log('sessionID ' + socket.handshake.sessionID);
});
On Server side
io.on('connection', socket => {
console.log(socket.id)
})
On Client side
import io from 'socket.io-client';
socket = io.connect('http://localhost:5000');
socket.on('connect', () => {
console.log(socket.id, socket.io.engine.id, socket.json.id)
})
If socket.id, doesn't work, make sure you call it in on('connect') or after the connection.
For some reason
socket.on('connect', function() {
console.log(socket.io.engine.id);
});
did not work for me. However
socket.on('connect', function() {
console.log(io().id);
});
did work for me. Hopefully this is helpful for people who also had issues with getting the id. I use Socket IO >= 1.0, by the way.
Try from your code
socket.socket.sessionid
ie.
var socket = io.connect('http://localhost');
alert(socket.socket.sessionid);
var sendBtn= document.getElementById('btnSend');
sendBtn.onclick= function(){
var userId=document.getElementById('txt1').value;
var userMsg = document.getElementById('txt2').value;
socket.emit('sendto',{username: userId, message: userMsg});
};
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
socket.on('message',function(data){ console.log(data);});
Try this way.
var socket = io.connect('http://...');
console.log(socket.Socket.sessionid);

Categories