Getting socket.io, express & node-http2 to communicate though HTTP/2

淺唱寂寞╮ 提交于 2020-12-31 06:03:32

问题


I wrote a Web Socket server using socket.io, node-http2 and express in Node.js. The server works as intended, except for the fact that according to Chrome's DevTools socket.io's negotiation requests go through HTTP/1.1 (shown below). The "Protocol" column should be displaying h2 if the request was sent using HTTP/2.

This only happens in Chrome, other browsers use the correct protocol.

The server code (shortened):

var PORT = 8667,
    config = require('./config'),
    socketioServer = require('socket.io'),
    app = express(),
    https = require('http2'),
    cors = require('cors');

app.use(cors(function(req, callback){
    var corsOptions = { origin: false };
    if (/^https:\/\/mlpvc-rr\.lc/.test(req.header('Origin')))
        corsOptions.origin = true;
    callback(null, corsOptions);
}));

app.get('/', function (req, res) {
  res.sendStatus(403);
});

var server = https.createServer({
    cert: fs.readFileSync(config.SSL_CERT),
    key: fs.readFileSync(config.SSL_KEY),
}, app);
server.listen(PORT);
var io = socketioServer.listen(server);
// ...

Browser connection code:

var conn = io('https://ws.'+location.hostname+':8667/', { reconnectionDelay: 5000 });
conn.on('connect', function(){
    console.log('[WS] Connected');
});
conn.on('disconnect',function(){
    console.log('[WS] Disconnected');
});

Output of testssl.sh:

What do I need to change to make the socket.io requests go through HTTP/2?


回答1:


As discussed in comments Chrome has recently stopped allowing the older NPN negotiation for HTTP/2 and insists on the newer ALPN protocol instead. See this article for more info: https://ma.ttias.be/day-google-chrome-disables-http2-nearly-everyone-may-31st-2016/

So you basically need Node.js to support ALPN which it looks as has only been added in v5 so far: https://github.com/nodejs/node/pull/2564 . An alternative would be to route your NodeJs calls through a webserver which is easier to upgrade OpenSSL (e.g. Nginx or Apache) to support HTTP/2 over ALPN.

You confirmed this was the issue by using the testssl.sh program which confirmed no ALPN support and the fact Firefox uses HTTP/2.




回答2:


A little bit late but with Express4 and Spdy (npm) is working great.

bin/www:

var app = require('../app');
var debug = require('debug')('gg:server');
var spdy = require('spdy');
var fs = require('fs');
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var options = {
    key: fs.readFileSync(__dirname + '/server.key'),
    cert: fs.readFileSync(__dirname + '/server.crt')
}
var server = spdy.createServer(options, app);
var io = app.io
io.attach(server);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
...

app.js:

...
var app = express();
var io = app.io = require('socket.io')();
...

client screenshot:



来源:https://stackoverflow.com/questions/38662677/getting-socket-io-express-node-http2-to-communicate-though-http-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!