NGINX在相关部分看起来如此:
listen 9443 ssl;
server_name example.com;
ssl_certificate mycert.crt;
ssl_certificate_key mykey.key;
ssl_client_certificate myca.pem;
ssl_verify_client on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8443/;
socketio / node.js应用程序如下所示:
var restify = require('restify');
var server = restify.createServer();
var io = require('socket.io') (server.server);
server.listen(8443, function () {
console.log('socket.io server listening at %s', server.url);
});
io.sockets.on('connection', function (socket) {
console.log("Client connected in io.sockets.on.connection");
socket.on('testfunc', function () {
console.log("this is testfunc");
});
socket.on('disconnect', function(){
console.log("Client disconnected");
});
});
index.html看起来像这样:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="socket.io.js"></script>
<script>
$(document).ready(function() {
var socket = io('https://example.com:9443', {secure: true});
socket.on('connect', function () {
socket.emit('testfunc');
});
});
</script>
NGINX侦听端口9443。 端口8443上的Node.js。
如果这个指令: ssl_verify_client on;
在nginx.conf中删除,那没问题。客户端连接后,它将在socket.io上调用“testfunc”。工作正常。
如果ssl_verify_client开启;在nginx.conf中会发生以下情况:
客户端似乎想连续连接到socket.io.不是无限循环。它将尝试每1秒连接一次。 emit(testunc)永远不会到达。不在客户端而不在服务器上。
我真的不明白问题是什么。我现在唯一可以看到的,也许是一个线索,就是每一秒 客户端尝试连接的URL具有不同的ID,如下所示:
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570178744-3&sid=A_HsCwcklo30ZlifAAAA
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570179958-5&sid=gU1Nlv6asTakgE0KAAAB
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570181232-11&sid=Oy6ZnW3PZbK8cojHAAAC
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570182456-15&sid=-uK6YnSkYUyjPdI9AAAD
新发现。问题是套接字请求没有发送客户端证书。此外,问题只存在于firefox中(我只对firefox和chrome感兴趣)。在Chrome中它可以工作。
只有在您指示请求发送客户端证书时,才能执行常规的ajax请求:
$.ajax({
url: 'https://example.com:9443/test',
type: 'GET',
xhrFields: {'withCredentials': true}
}).success(function (value) {
console.log(value)
console.log('success');
}).error(function () {
console.log(arguments);
console.log('error');
});
上述请求适用于两种浏览器。
现在,在进行套接字连接时,它会失败。它在Firefox中失败了。但它适用于Chrome。 我试图找出如何在socket.io上编写一个模仿ajax-request中的“withCredentials”-option的选项..但没有运气。 另外:在Chrome中进行套接字连接工作而不设置任何“withCredentials”选项。听起来Chrome默认发送客户端证书。
更有趣的是:两个浏览器在尝试建立套接字连接时使用了哪些协议?似乎两者都通过调用socket.io并使用轮询作为传输来进行一些测试。然后这两者都依赖于websocket。最后的工作可能是: firefox和chrome都使用websocket连接到服务器。但是,在chrome中,证书是默认发送的(?),而在Firefox中则不是。