What you might have heard is not saving a socket into a session, but referencing sockets by their session cookie, which is passed to the server during the socket authorization process. During authorization, this is an example of the type of object that is passed to the server:
{
headers: req.headers, // <Object> the headers of the request
time: (new Date) +'', // <String> date time of the connection
address: socket.address(), // <Object> remoteAddress and remotePort object
xdomain: !!headers.origin, // <Boolean> was it a cross domain request?
secure: socket.secure, // <Boolean> https connection
issued: +date, // <Number> EPOCH of when the handshake was created
url: request.url, // <String> the entrance path of the request
query: data.query // <Object> the result of url.parse().query or a empty object
}
What we're interested in is the headers property, where we can find the session cookies of a connecting socket. We then parse the cookies during authorization:
// pass same objects from Express to Socket.IO so they match
var parseCookie = express.cookieParser(SITE_SECRET);
var store = new MongoStore({
mongoose_connection: mongoose.connection,
db: mongoose.connections[0].db
});
io.configure(function() {
io.set('authorization', function(handshake, callback) {
if (handshake.headers.cookie) {
parseCookie(handshake, null, function(err) {
// we used the signedCookies property since we have a secret
// save the session ID to the socket object, we can access it later
handshake.sessionID = handshake.signedCookies['connect.sid'];
store.get(handshake.sessionID, function(err, session) {
// we have the same Express session, reference it
socket.session = session;
callback(null, true);
});
});
} else {
// they client has no session yet, don't let them connect
callback('No session.', false);
}
});
});
app.use(parseCookie);
app.use(express.session({
secret: SITE_SECRET,
store: store,
cookie: {maxAge: new Date(Date.now() + (1000*60*60*24*30*12))}
}));
Then once we have saved the session ID, we can use the typical connection events:
var server = require('http').createServer(app)
var io = require('socket.io').listen(server);
var clients = {};
io.sockets.on('connection', function (socket) {
// save to a global object
var session = socket.handshake.sessionID;
clients[session] = socket;
socket.on('disconnect', function() {
delete clients[session];
});
});
Then we have a global reference by cookie signature. We can then access the socket like this:
app.get('/path', function(req, res) {
var socket = clients[req.sessionID];
socket.emit('Socket client accessed route.');
});
Keep in mind you might have to add some logic into your global logic for clients with multiple tabs, which would result in two sockets with the same authorization cookie.
As for your question about using socket.on() and socket.emit(), you can't use that before the connection has been established because the socket itself does not exist. If you want to send a message to all connected clients, then you should just use the global io.sockets object. It would then be more like io.sockets.emit().