提前为这么长的问题道歉,我只是想确保我涵盖了所有内容…
我有一个react应用程序,它应该连接到我部署到kubernetes的服务中运行的套接字。服务运行正常,工作正常。我可以在没有任何问题的情况下发出请求,但我无法连接到在同一服务中运行的websocket。
当我在本地运行服务并使用localhost uri时,我能够连接到websocket。
我的快递服务服务器。文件如下:
import "dotenv/config";
import * as packageJson from "./package.json"
import service from "./lib/service";
const io = require("socket.io");
const PORT = process.env.PORT;
const server = service.listen(PORT, () => {
console.info(`Server up and running on ${PORT}...`);
console.info(`Environment = ${process.env.NODE_ENV}...`);
console.info(`Service Version = ${packageJson.version}...`);
});
export const socket = io(server, {
cors: {
origin: process.env.ACCESS_CONTROL_ALLOW_ORIGIN,
methods: ["GET", "POST"]
}
});
socket.on('connection', function(skt) {
console.log('User Socket Connected');
socket.on("disconnect", () => console.log(`${skt.id} User disconnected.`));
});
export default service;
当我运行这个时,PORT
被设置为8088,access-control-allow-origin被设置为*
。请注意,我使用的是部署到Kubernetes的rabbitmq集群,当我在本地运行时,rabbit连接的uri是相同的。Rabbitmq没有在我的本地机器上运行,所以我知道这不是我的rabbit部署的问题,它必须是我在连接到套接字时做错了。
当我在本地运行服务时,我可以在react应用程序中使用以下命令进行连接:
const io = require("socket.io-client");
const socket = io("ws://localhost:8088", { path: "/socket.io" });
我看到"用户套接字已连接">
当我将服务部署到Kubernetes时,我在确定如何连接到套接字时遇到了一些问题。
My Kubernetes Service:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8088
selector:
app: my-service
我部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 2
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: project
image: my-private-registry.com
ports:
- containerPort: 8088
imagePullSecrets:
- name: mySecret
最后,我的入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-service-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/enable-cors: "true" // Just added this to see if it helped
nginx.ingress.kubernetes.io/cors-allow-origin: "*" // Just added this to see if it helped
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS, DELETE, PATCH // Just added this to see if it helped
spec:
tls:
- hosts:
- my.host.com
secretName: my-service-tls
rules:
- host: "my.host.com"
http:
paths:
- pathType: Prefix
path: "/project"
backend:
service:
name: my-service
port:
number: 80
我可以连接到服务并获得数据,发布数据等,但我无法连接到websocket,我得到404或cors错误。
由于服务运行在my.host.com/project上,我假设套接字位于相同的uri。所以我试着连接:
const socket = io("ws://my.host.com", { path: "/project/socket.io" });
和使用wss://
const socket = io("wss://my.host.com", { path: "/project/socket.io" });
和我有一个错误记录在控制台:
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
都产生
polling-xhr.js?d33e:198 GET https://my.host.com/project/?EIO=4&transport=polling&t=NjWQ8Tc 404
websocket.ts?25e3:14 connect_error due to xhr poll error
我尝试了以下所有方法,但都不起作用:
const socket = io("ws://my.host.com", { path: "/socket.io" });
const socket = io("wss://my.host.com", { path: "/socket.io" });
const socket = io("ws://my.host.com", { path: "/project" });
const socket = io("wss://my.host.com", { path: "/project" });
const socket = io("ws://my.host.com", { path: "/" });
const socket = io("wss://my.host.com", { path: "/" });
const socket = io("ws://my.host.com");
const socket = io("wss://my.host.com");
同样,当服务在本地运行时,这是有效的,所以我一定是错过了什么,任何帮助将非常感激。
是否有一种方法可以在Kubernetes pod上找到rabbit被广播到的地方?
万一将来有人偶然发现了这个问题,想知道如何修复它,结果证明这是我犯的一个非常愚蠢的错误。
:
export const socket = io(server, {
cors: {
origin: process.env.ACCESS_CONTROL_ALLOW_ORIGIN,
methods: ["GET", "POST"]
},
});
我只需要将path: "/project/socket.io"
添加到套接字选项中,这是有意义的。
然后如果有人碰巧遇到接下来的问题,我在websocket轮询的帖子上得到了400个错误,所以我在套接字中设置了transports: [ "websocket" ]
。Io-client选项,这似乎解决了这个问题。插座现在工作了,我终于可以继续前进了!