我正在使用 Nginx 提供前端静态文件,如下所示。
server {
server_name <my_domain>;
root /usr/share/nginx/myproject/dist;
index index.htm index.html;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/host.error.log notice;
location /socket.io/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass https://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / {
try_files $uri $uri/ =404;
}
listen 443 ssl; # managed by Certbot
ssl_certificate # managed by Certbot
ssl_certificate_key # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
当我访问域名地址时,我可以很好地看到前端,但它没有与后端建立任何 websocket 连接。没有任何错误,请求仅针对前端内容。 我的服务器代码如下所示。
import { readFileSync } from 'fs';
import http from 'http';
import https from 'https';
import express from "express";
import { Server } from 'socket.io';
import cors from "cors";
const app = express();
app.use(cors);
let server;
if (process.env.NODE_ENV == "development") {
server = http.createServer(app);
} else {
server = https.createServer({
cert: readFileSync("/etc/letsencrypt/live/<my_domain>/cert.pem", "utf8"),
key: readFileSync("/etc/letsencrypt/live/<my_domain>/privkey.pem", "utf8"),
ca: readFileSync("/etc/letsencrypt/live/<my_domain>/chain.pem", "utf8"),
}, app);
}
let origin;
if (process.env.NODE_ENV == "development") {
origin = "http://localhost:5173";
} else {
origin = "http://<domain_name>";
}
const io = new Server(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
},
});
io.on('connection', (sock) => {
sock.on('disconnect', (sock_id) => {
console.log('user disconnected.')
})
});
server.on('error', (err) => console.error(err));
server.listen(8000, () => {
console.log('server is ready on 8000');
})
客户端在单个组件中使用套接字对象,导出如下。
import { io, Socket } from "socket.io-client";
import { ServerToClientEvents, ClientToServerEvents } from "./types";
let socket: Socket<ServerToClientEvents, ClientToServerEvents>;
if (process.env.NODE_ENV == 'development') {
socket = io("http://localhost:8000",);
} else {
socket = io(
"https://<my_domain>/", { transports: ["websockets"], });
}
export default socket;
当然,我已经在开发中进行了测试,但它无法在我的 VPS 主机上运行。我已经尝试了 socket.io documentations 上提到的自定义路径。 我已经为我的 Express 后端尝试了 http 和 https 服务器。 我在 nginx 配置上尝试了 localhost 和 127.0.0.1。 我已经尝试了服务器的多个端口。
我通过从客户端删除 { Transports: ["websockets"] } 来修复它,在服务器端我删除了 CORS 中的方法选项并使源点指向我的域。