配置
HTTP/1.1協(xié)議中Upgrade機(jī)制可以將http升級到WebSocket,實(shí)現(xiàn)客戶端與服務(wù)端的雙向通訊。
客戶端需要升級協(xié)議時(shí)在請求頭包含Upgrade、Connection字段。
如果服務(wù)端同意升級連接,就會(huì)返回101狀態(tài)碼和一個(gè)Upgrade標(biāo)頭字段,Upgrade字段內(nèi)容為要切換到的協(xié)議。
如果服務(wù)器不能升級連接,返回一個(gè)常規(guī)響應(yīng),如200 ok。
nginx實(shí)現(xiàn)代理WebSocket,在轉(zhuǎn)發(fā)請求時(shí)需要在請求頭中包含Upgrade、Connection兩個(gè)字段。
Upgrade表示希望升級到的協(xié)議,值從客戶端請求中取。
Connection值為upgrade時(shí)表示希望升級的協(xié)議,為close時(shí)表示關(guān)閉連接。配置案例:
map $http_upgrade $connection_upgrade {
# 客戶端請求頭中存在Upgrade字段時(shí),$connection_upgrade變量值為upgrade
default upgrade;
# 客戶端請求中沒有Upgrade,變量值為close
'' close;
}
upstream proxy_websocket {
server 192.168.1.16:6066;
}
server {
listen 6066;
location / {
proxy_pass http://proxy_websocket;
# 只有HTTP/1.1協(xié)議提供Upgrade機(jī)制,HTTP/2 明確禁止使用此機(jī)制
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
驗(yàn)證
搭建WebSocket服務(wù),server.js:
const { Server } = require("ws");
const server = new Server({ port: 6066 });
console.log("WebSocket服務(wù)監(jiān)聽6066端口...");
server.on("connection", (client) => {
console.log("建立新連接");
client.on("message", (msg) => {
console.log("收到客戶端消息:%s", msg);
// 給客戶端發(fā)送消息
client.send(Math.random());
});
client.on("close", () => {
console.log("與客戶端的連接斷開");
});
});
啟動(dòng)服務(wù) node server.js
const WebSocket = require("ws");
// WebSocket連接nginx代理服務(wù)器192.168.1.18
const socket = new WebSocket("ws://192.168.1.18:6066/");
socket.on("open", () => {
console.log("與WebSocket服務(wù)端連接成功");
socket.send("hello world");
});
socket.on("message", (data) => {
console.log("收到消息:" + data.toString());
});
socket.on("close", () => {
console.log("WebSocket關(guān)閉");
});
socket.on("error", (err) => {
console.error("WebSocket錯(cuò)誤:", err);
});
啟動(dòng)客戶端,node client.js
閱讀原文:原文鏈接
該文章在 2025/7/1 23:46:32 編輯過