我正在使用 Socket.IO 服务器和客户端应用程序。以下是我的客户端代码:
this.socket = io("https://my-server-app.cloudapp.azure.com", {
transports: ["websocket"],
path: "/nodeserver/socket.io/",
auth: {
userId: userId,
token: token,
},
});
Socket.IO 服务器部署在 AKS 集群中。这是服务器端代码:
var io = require('socket.io')(app.listen(port), { path: "/nodeserver/socket.io/" });
io.sockets.on('connection', function (socket) {
console.log("Handshake data:", socket.handshake);
console.log(JSON.stringify(socket.handshake.auth));
});
问题 在本地运行应用程序时(localhost:8083),握手数据中的 auth 变量已正确填充,如日志中所示:
Handshake data: {
headers: {
host: 'localhost:8083',
connection: 'Upgrade',
pragma: 'no-cache',
'cache-control': 'no-cache',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
upgrade: 'websocket',
origin: 'http://localhost:4200',
'sec-websocket-version': '13',
'accept-encoding': 'gzip, deflate, br, zstd',
'accept-language': 'en-US,en;q=0.9',
'sec-websocket-key': 'ATD5Ct1HLN3FDAajDfRfIQ==',
'sec-websocket-extensions': 'permessage-deflate; client_max_window_bits'
},
time: 'Thu Dec 19 2024 11:36:44 GMT+0530 (India Standard Time)',
address: '::1',
xdomain: true,
secure: false,
issued: 1734588404811,
url: '/nodeserver/socket.io/?EIO=4&transport=websocket',
query: [Object: null prototype] { EIO: '4', transport: 'websocket' },
auth: {
userId: '[email protected]',
token: 'mytoken'
}
}
但是,当通过 AKS 部署的 URL (https://my-server-app.cloudapp.azure.com) 访问服务器时,握手数据中的 auth 字段丢失:
Handshake data: {
headers: {
host: 'https://my-server-app.cloudapp.azure.com',
connection: 'Upgrade',
pragma: 'no-cache',
'cache-control': 'no-cache',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
upgrade: 'websocket',
origin: 'http://localhost:4200',
'sec-websocket-version': '13',
'accept-encoding': 'gzip, deflate, br, zstd',
'accept-language': 'en-US,en;q=0.9',
'sec-websocket-key': 'ATD5Ct1HLN3FDAajDfRfIQ==',
'sec-websocket-extensions': 'permessage-deflate; client_max_window_bits'
},
time: 'Thu Dec 19 2024 12:20:20 GMT+0530 (India Standard Time)',
address: '::1',
xdomain: true,
secure: false,
issued: 1734588404811,
url: '/nodeserver/socket.io/?EIO=4&transport=websocket',
query: [Object: null prototype] { EIO: '4', transport: 'websocket' }
}
Socket.IO 服务器:
"socket.io": "^4.7.5"
和
Socket.IO 客户端:"socket.io-client": "^4.8.1"
。
本地测试时auth对象正确传递。
通过 AKS 部署的 URL 访问时,它不会出现。
预期结果 auth 对象应包含在本地和部署环境的握手数据中。
如何确保在AKS环境中正确传输和记录身份验证数据?
问题是
Socket.IO
在初始 WebSocket 握手中传输身份验证数据,但如果代理或负载均衡器删除这些标头或修改握手,则身份验证数据可能会丢失。
下面是我如何在
ingress.yaml
文件中使用代理设置标头的示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
appgw.ingress.kubernetes.io/backend-protocol: "http"
appgw.ingress.kubernetes.io/request-timeout: "60"
appgw.ingress.kubernetes.io/proxy-set-header: "Upgrade $http_upgrade"
appgw.ingress.kubernetes.io/proxy-set-header.Connection: "upgrade"
spec:
ingressClassName: azure-application-gateway
rules:
- host: my-server-app.cloudapp.azure.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-server-service
port:
number: 3000
有关 Kubernetes 注释的详细信息,请参阅此链接。
对于
service.yaml
,请使用以下配置:
apiVersion: v1
kind: Service
metadata:
name: socketio-service
spec:
selector:
app: socketio
ports:
- protocol: TCP
port: 3000
targetPort: 3000
type: ClusterIP
确保添加 cors 并确保 CORS 配置为允许来自所有域的请求:
path: "/nodeserver/socket.io/",
cors: {
origin: "*",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true,
},
});
构建映像,使用 Azure 容器注册表对其进行标记,然后将其推送到注册表。
然后,使用此指南创建 Kubernetes 服务。使用 ACR 映像通过 YAML 文件将应用程序部署到 AKS 集群。
以下是示例
deployment.yaml
我使用的:
apiVersion: apps/v1
kind: Deployment
metadata:
name: socketio-server
labels:
app: socketio
spec:
replicas: 2
selector:
matchLabels:
app: socketio
template:
metadata:
labels:
app: socketio
spec:
containers:
- name: socketio
image:samopath.azurecr.io/newfolder2-app:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: production
使用 Azure Cloud Shell 连接到 AKS 群集,并使用 Kubernetes 运行应用程序。请按照此教程了解更多详细信息。
使用
kubectl get deployment
检查部署状态。使用 kubectl get pods
检查 Pod 状态
列出当前命名空间中的所有服务
kubectl get services
。
使用 kubectl expose deployment socketio-server --type=NodePort --port=3000 --target-port=3000
将其公开为 NodePort 服务。
更新
socketio-server
服务以使用 LoadBalancer
使用
kubectl patch service socketio-server -p '{"spec": {"type": "LoadBalancer"}}'
要查看特定 Pod 的日志,请使用:
kubectl logs socketio-server-865b857564-c2mxx