在本地服务器上一切正常。但是,当我尝试通过Nginx
在远程服务器上进行测试时,事件处理程序onopen
中的readyState
总是CLOSED
。
Nginx配置:
server {
server_name domain.domain;
access_log /var/log/nginx/domain.domain.access.log;
error_log /var/log/nginx/domain.domain.error.log;
location / {
proxy_connect_timeout 1d;
proxy_send_timeout 1d;
proxy_read_timeout 1d;
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain.domain/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain.domain/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = domain.domain) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name domain.domain;
listen 80;
return 404; # managed by Certbot
}
服务器示例代码:
import { WebSocketServer } from 'ws';
this.connection = new WebSocketServer(args, () => {
log('info', 'Server listen at port:', args.port, true);
});
this.connection.on('connection', (ws, req) => {
// Event is triggered fine
console.log('Client connected');
})
客户样本代码:
const connection = new WebSocket(
'wss://domain.domain:443', 'json'
);
connection.onopen = () => {
// Event triggered bud connection.readyState is CLOSED every time
setInterval(() => {
console.log(connection.readyState);
}, 1000)
}
connection.onerror = () => {
// Never triggered
}
connection.onclose = () => {
// Never triggered
}
以前,使用相同服务器设置的相同代码运行良好。但过了一段时间,当我从备份中重新创建虚拟服务器时,出现了这样的问题,尽管其他一切都像以前一样工作。
再次查看我的代码,我发现自从上次成功测试以来,我向服务器添加了一个CORS检查,结果发现,该检查没有在环境变量中正确配置。
this.connection.on('connection', (ws, req) => {
// Event is triggered fine
console.log('Client connected');
const { origin } = req.headers;
const notAllowed = process.env.CORS.split(',').indexOf(origin || '') === -1;
if (cors && notAllowed) {
log('warn', 'Block CORS attempt', { headers: req.headers });
ws.close();
return;
}
})
另一个问题是为什么客户端上没有触发事件onclose
,以及为什么服务器上没有显示warn
。但我认为,由于我在stdout中使用了一个特殊的方法输出,可能由于环境变量不正确,它也不起作用,但这是另一个问题——这里不需要考虑它。