Reputation: 8178
<script src="/socket.io/socket.io.js"></script>
How does the browser know how to grab socket.io from that reference? The last time I checked, I didn't have a socket.io.js file in my public folder.
Update: Socket.io is working just fine, I'm just curious how it uses this mysterious route to get the client side socket.io code.
Thanks for the extensive answer : )
Upvotes: 1
Views: 227
Reputation: 707786
Actually, there is some slight magic here. When you install the server-side socket.io
library and initialize it by passing it your web server, it automatically installs a route handler into your web server for any request for /socket.io/socket.io.js
and it will serve a socket.io.js
file that is designed for the client from deep within the server-side socket.io installation directory whenever that particular /socket.io/socket.io.js
route is requested.
So, the file does not actually come from the exact path that is requested (that is just the route that a handler is installed for). The file actually comes from the server-side installation directory (inside of node_modules/socket.io
). The advantage of doing it this way is that since the server side implementation of socket.io and the client-side implementation are all coming from the exact same NPM installation, they are always guarenteed to be the same version so you never have an issue with client and server versions being out of sync.
For reference, here's the relevant part of the socket.io server code that serves /socket.io/socket.io.js
:
var clientSource = read(require.resolve('socket.io-client/socket.io.js'), 'utf-8');
Server.prototype.serve = function(req, res){
var etag = req.headers['if-none-match'];
if (etag) {
if (clientVersion == etag) {
debug('serve client 304');
res.writeHead(304);
res.end();
return;
}
}
debug('serve client source');
res.setHeader('Content-Type', 'application/javascript');
res.setHeader('ETag', clientVersion);
res.writeHead(200);
res.end(clientSource);
};
/**
* Attaches the static file serving.
*
* @param {Function|http.Server} http server
* @api private
*/
Server.prototype.attachServe = function(srv){
debug('attaching client serving req handler');
var url = this._path + '/socket.io.js';
var evs = srv.listeners('request').slice(0);
var self = this;
srv.removeAllListeners('request');
srv.on('request', function(req, res) {
if (0 === req.url.indexOf(url)) {
self.serve(req, res);
} else {
for (var i = 0; i < evs.length; i++) {
evs[i].call(srv, req, res);
}
}
});
};
Upvotes: 2