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.
我在Node.js中使用socket.io,node-http2和express编写了一个Web Socket服务器。服务器按预期工作,除了根据Chrome的DevTools socket.io的协商请求通过HTTP / 1.1(如下所示)这一事实。如果请求是使用HTTP / 2发送的,则“协议”列应显示h2。
This only happens in Chrome, other browsers use the correct protocol.
这只发生在Chrome中,其他浏览器使用正确的协议。
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:
testssl.sh的输出:
What do I need to change to make the socket.io requests go through HTTP/2?
我需要更改什么才能使socket.io请求通过HTTP / 2?
1 个解决方案
#1
2
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/
正如评论中所讨论的,Chrome最近已经停止允许HTTP / 2的旧NPN协商,而是坚持使用更新的ALPN协议。有关详细信息,请参阅此文章: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.
所以你基本上需要Node.js来支持ALPN,它看起来只是到目前为止在v5中添加的:https://github.com/nodejs/node/pull/2564。另一种方法是通过Web服务器路由您的NodeJs调用,这更容易升级OpenSSL(例如Nginx或Apache)以支持ALPN上的HTTP / 2。
You confirmed this was the issue by using the testssl.sh program which confirmed no ALPN support and the fact Firefox uses HTTP/2.
您通过使用testssl.sh程序确认这是问题,该程序确认没有ALPN支持以及Firefox使用HTTP / 2的事实。
#1
2
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/
正如评论中所讨论的,Chrome最近已经停止允许HTTP / 2的旧NPN协商,而是坚持使用更新的ALPN协议。有关详细信息,请参阅此文章: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.
所以你基本上需要Node.js来支持ALPN,它看起来只是到目前为止在v5中添加的:https://github.com/nodejs/node/pull/2564。另一种方法是通过Web服务器路由您的NodeJs调用,这更容易升级OpenSSL(例如Nginx或Apache)以支持ALPN上的HTTP / 2。
You confirmed this was the issue by using the testssl.sh program which confirmed no ALPN support and the fact Firefox uses HTTP/2.
您通过使用testssl.sh程序确认这是问题,该程序确认没有ALPN支持以及Firefox使用HTTP / 2的事实。