socket.io parse connect (>= 2.4.1) signed session cookie - javascript

With the latest version of connect (as of 2012-07-26), I've found the following way to get a session ID from socket.io that will work with a connect-redis store.
var express = require('express')
, routes = require('./routes')
, fs = require('fs')
, http = require('http')
, io = require('socket.io')
, redis = require('connect-redis')
, connect = require('express/node_modules/connect')
, parseSignedCookie = connect.utils.parseSignedCookie
, cookie = require('express/node_modules/cookie');
var secret = '...';
var rStore = new(require('connect-redis')(express));
//...
var server = http.createServer(app);
var sio = io.listen(server);
sio.set('authorization', function(data, accept) {
if(data.headers.cookie) {
data.cookie = cookie.parse(data.headers.cookie);
data.sessionID = parseSignedCookie(data.cookie['connect.sid'], secret);
} else {
return accept('No cookie transmitted', false);
}
accept(null, true);
});
data.sessionID can then be used later such as
sio.sockets.on('connection', function(socket) {
console.log('New socket connection with ID: ' + socket.handshake.sessionID);
rStore.get(socket.handshake.sessionID, function(err, session) {
//...
});
});
Having to import so many from express (connect, a utility of connect, and the cookie module) seems like an overly roundabout way of getting the functions needed to parse connect's signed cookies. Has anyone found another way?

I was running into the same and just wrote a tiny module to abstract it. Here's how its usage looks like. It was written and tested using express 3 so should work fine with connect 2.4.x. Please let me know otherwise.
var SessionSockets = require('session.socket.io')
, sessionSockets = new SessionSockets(io, sessionStore, cookieParser);
sessionSockets.on('connection', function (err, socket, session) {
//your regular socket.io code goes here
});
For more details on how it works see https://github.com/wcamarao/session.socket.io

Related

How to make the websocket server be at a router?

I'm writing a websocket server using nodejs-ws module, but the server can only be at the root of the server, so how I can make it at a child router like localhost:3000/chat?
I need your help, thanks a lot!
Working example:
var ws = require('ws');
var http = require('http');
var httpServer = http.createServer();
httpServer.listen(3000, 'localhost');
var ws1 = new ws.Server({server:httpServer, path:"/chat"});
ws1.on('connection', function(){
console.log("connection on /chat");
});
var ws2 = new ws.Server({server:httpServer, path:"/notifications"});
ws2.on('connection', function(){
console.log("connection on /notifications");
});
could you please tell me how to use this in express?
To route websockets with Express I'd rather use express-ws-routes
var express = require('express');
var app = require('express-ws-routes')();
app.websocket('/myurl', function(info, cb, next) {
console.log(
'ws req from %s using origin %s',
info.req.originalUrl || info.req.url,
info.origin
);
cb(function(socket) {
socket.send('connected!');
});
});

Node-HTTP-Proxy error

I am trying to implement a node http proxy for the first time with my simple twitter tweeter. I have never used this before and tried following the docs (https://github.com/nodejitsu/node-http-proxy) with no luck. Can anyone point me in the right direction? Also, is it okay to run this locally on a mac? Thanks
var express = require('express');
var app = express();
var port = 8300;
var twitter = require('twitter');
var twit = new twitter({ keys and stuff })
var http = require('http'),
httpProxy = require('http-proxy');
twit.post('statuses/update', {status: "Hello world!"}
//this works
httpProxy.createProxyServer({target:'http://localhost:3000'}).listen(3000);
// Create your target server--- WHat exactly does this mean??
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(3000);
You should not use this lib for proxing you request. This lib is for make your own proxy server. Look at example how to use proxy with twitter lib

How to get list of connected users in PeerJS server (with express)?

I'm trying to use PeerJS (a webRTC library) for a game and triyng to use the server they provide for doing user discovery. I want to manage a list of connected users and I'm struggling with PeerJS server.
In the doc they say we can have a PeerJs and an Express server in the same app.
Here is the code :
// this doesn't work
var express = require('express');
var app = express();
var ExpressPeerServer = require('peer').ExpressPeerServer;
app.get('/', function(req, res, next) { res.send('Hello world!'); });
var server = app.listen(9000);
var options = {
debug: true,
allow_discovery: true
}
app.use('/api', ExpressPeerServer(server, options));
server.on('connection', function(id) {
// we get a socket object as id :(
// should be a string
console.log(id)
});
server.on('disconnect', function(id) { console.log(id + "deconnected") });
Nevertheless, when a user connects, I get a socket object as id, which is not what I want. Also I can't access to the connected peers at the url http://localhost:9000/peerjs/peers
What is strange is that, using only PeerJS server, it works as expected (I get the string ID of the peer), and I can access to the connected peers at the url http://localhost:9000/peerjs/peers.
// this works
var ip = require('ip');
var PeerServer = require('peer').PeerServer;
var port = 9000;
var server = new PeerServer({port: port, allow_discovery: true});
server.on('connection', function (id) {
// id is correct (a string)
console.log('new connection with id ' + id);
});
server.on('disconnect', function (id) {
console.log('disconnect with id ' + id);
});
console.log('peer server running on ' +
ip.address() + ':' + port);
Any clues to make PeerJS server work with express ?
Is it a regression about the express compatibility ?
Thanks a lot :)
System infos :
node -v : v0.10.25
Ubuntu 14.04
peerJS server installed from github with : npm install peers/peerjs-server (version: "0.2.8")
var app = express();
var server = app.listen(8000);
var q = ExpressPeerServer(server, options);
app.use('/peer', q);
q.on('connection', function (id) {
console.log('user with ', id, 'connected');
});
this should work
Just incase anyone having same issue all you need to do is:
server.on('disconnect', function (client)
{
// this will give you id in text or whatever format you are using
console.log('disconnect with id ' + client.id);
});
You can use the undocumented listAllPeers(function cb(list){}) function if you run your own peerjs-server.
Just a reference to your own answer here: https://github.com/peers/peerjs-server/issues/86
And in combination with SocketIO: http://stephantabor.com/2015/07/11/express-peerjs-and-socket-io/

express.js parsing cookies?

I am trying to use an old library balloons.io as a base for a chat app, but it's quite out dated, in this particular code I am trying to figure out how to use express 4x to parse the cookie to get an sid without getting it from the req.session
Since express 4x is not using connect anymore how can I do something similar to the below but in the new express version?
/*
* Module dependencies
*/
var sio = require('socket.io')
, parseCookies = require('connect').utils.parseSignedCookies
, cookie = require('cookie')
, fs = require('fs');
/**
* Expose Sockets initialization
*/
module.exports = Sockets;
/**
* Socket.io
*
* #param {Express} app `Express` instance.
* #param {HTTPServer} server `http` server instance.
* #api public
*/
function Sockets (app, server) {
var config = app.get('config');
var client = app.get('redisClient');
var sessionStore = app.get('sessionStore');
var io = sio.listen(server);
io.set('authorization', function (hsData, accept) {
if(hsData.headers.cookie) {
var cookies = parseCookies(cookie.parse(hsData.headers.cookie), config.session.secret)
, sid = cookies['balloons'];
sessionStore.load(sid, function(err, session) {
if(err || !session) {
return accept('Error retrieving session!', false);
}
hsData.balloons = {
user: session.passport.user,
room: /\/(?:([^\/]+?))\/?$/g.exec(hsData.headers.referer)[1]
};
return accept(null, true);
});
} else {
return accept('No cookie transmitted.', false);
}
});
});
};
Not sure if this helps, but Cookie parsing in express 4.x has been extracted to the cookie-parser package. I'm not sure, but you may be able to swap out connect.util.parseSignedCookies with cookieParser.parseSignedCookies`.
That's about all I can help you with, as I haven't used socket.io much yet.
function Sockets (app, server, pub, sub, sessionStore) {
var config = app.get('config');
var secrets = require('./config/secrets');
var client = pub;
var io = sio.listen(server);
io.set('authorization', function (handshake, callback) {
if(handshake.headers.cookie) {
// pay attention here, this is how you parse, make sure you use
// cookie-parser and cookie
var cookies = cookie.parse(handshake.headers.cookie);
var sid = cookieParser.signedCookie(cookies['balloons'], secrets.sessionSecret);
// get the session data from the session store
sessionStore.load(sid, function(err, session) {
if(err || !session) {
return callback('Error retrieving session!', false);
}
// this is not storing the data into the handshake object
handshake.headers.xygaming = {
user: session.passport.user,
room: /\/(?:([^\/]+?))\/?$/g.exec(handshake.headers.referer)[1]
};
return callback(null, true);
});
} else {
return callback('No cookie transmitted.', false);
}
});
}

socket.io reconnect socket.socket.connect doesn't work

sorry for posting this issue again, but most of the posts related don't answer my question.
i'm having issues to use multiple connections with the socket.io
i don't get the "socket.socket.connect" method to work, yet i get feedbacks from the first connection.
Here's my structure:
var iosocket = null;
var firstconnection = true;
var ip = "http://xxx.xxx.xxx"
var ipPort = 8081
function callSocket() {
iosocket = null;
iosocket = io.connect(ip,{port:ipPort,rememberTransport:true, timeout:1500});
if (firstconnection) {
firstconnection= false;
iosocket = io.connect(ip,{port:ipPort,rememberTransport:true, timeout:1500});
iosocket.on('connect', function () {console.log("hello socket");});
iosocket.on('message', function(message) {});//end of message io.socket
iosocket.on('disconnect', function () {console.log("disconnected");});
} else {
if (iosocket.connected === true) {
console.log("heyhey still connected");
iosocket.disconnect();
}
iosocket.socket.connect(ip,{port:ipPort,rememberTransport:true,timeout:1500});
}
};
it simply doesn't get any feedback from the second connection
i simply solved that IE8 bug by adding
<!DOCTYPE html>
at the top of the html
I think I know why this isn't working. For server-side code, this doesn't seem correct for socket.io. The connect method is used for clients and not servers. I think you are trying to make the server listen on a port. In that case, you should do:
var socket = require('socket.io');
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
var io = socket.listen(server);
io.on('connection', function (client) {
client.on('someEvent', function(someVariables){
//Do something with someVariables when the client emits 'someEvent'
io.emit('anEventToClients', someData);
});
client.on('anotherEvent', function(someMoreVariables){
//Do more things with someMoreVariables when the client emits 'anotherEvent'
io.emit('anotherEventToClients', someMoreData);
});
});
server.listen(8000);

Categories

Resources