首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Web服务器-Nginx代理WebSocket

Web服务器-Nginx代理WebSocket

作者头像
运维小路
发布2025-04-11 15:18:33
发布2025-04-11 15:18:33
3560
举报
文章被收录于专栏:运维小路运维小路

作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

我们上一大章介绍了Kubernetes的知识,本章节我们进入中间件的讲解,这里会包含很多不同的类型组件,中间件的第一个大类我这里定义的是Web服务器。由于目前使用最广泛的Web服务器是Nginx,所以我们这里的讲解主要以Nginx服务器为主。

今天我们来介绍一种特殊后端服务WebSocket,他的配置和普通网站代理很不一样。WebSocket 是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器之间的数据交换变得更加简单,允许服务器主动向客户端推送数据。正常我们请求普通网页,只有我们主动向服务器发起请求,服务端不能主动向我们推送请求。

1.构建一个WebSocket服务

定义主动推送数据给客户端,推送的当前时间,每10秒一次。

代码语言:javascript
复制
#安装pip命令
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
python get-pip.py
#安装依赖软件
yum -y install python-devel
#安装websocket支持 
pip install autobahn==0.10.4 twisted==15.5.0
代码语言:javascript
复制
#python的WebSocket服务 
# -*- coding: utf-8 -*-
import time
import random
import json  # 新增导入 json 模块
from twisted.internet import reactor
from autobahn.twisted.websocket import WebSocketServerFactory, WebSocketServerProtocol
import txaio

txaio.use_twisted()

class MyServerProtocol(WebSocketServerProtocol):
    def __init__(self):
        super(MyServerProtocol, self).__init__()
        self.task = None

    def onOpen(self):
        print(u"[服务端] 客户端连接成功")
        self.start_pushing()

    def start_pushing(self):
        def push():
            data = {
                u"time": u"当前时间: {}".format(time.strftime("%Y-%m-%d %H:%M:%S")),
                u"value": u"随机值: {:.2f}".format(random.random())
            }
            # 将数据转换为 JSON 字符串并编码为 UTF-8 字节
            json_data = json.dumps(data, ensure_ascii=False).encode('utf-8')
            self.sendMessage(json_data)
            self.task = reactor.callLater(10, push)
        self.task = reactor.callLater(0, push)

    def onClose(self, wasClean, code, reason):
        print(u"[服务端] 客户端断开连接")
        if self.task and self.task.active():
            self.task.cancel()

if __name__ == '__main__':
    factory = WebSocketServerFactory(u"ws://0.0.0.0:9000")
    factory.protocol = MyServerProtocol
    reactor.listenTCP(9000, factory)
    print(u"[服务端] 服务已启动,监听端口 9000")
    reactor.run()

前端代码,保存为xxx.html,然后使用浏览器打开,这个时候还没有引入Nginx代理,是浏览器直接访问WebSocket服务。

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"> <!-- 必须指定编码 -->
    <title>WebSocket 测试</title>
</head>
<body>
    <div id="output"></div>
    <script>
        var ws = new WebSocket('ws://192.168.31.121:9000');
        ws.onmessage = function(event) {
            var data = JSON.parse(event.data);  // 解析 JSON
            document.getElementById('output').innerHTML = 
                data.time + "<br>" + data.value;
        };
    </script>
</body>
</html>
代码语言:javascript
复制
#当前未使用代理的,直接访问WebSoket的情况 
当前时间: 2025-04-06 11:21:01随机值: 0.07
当前时间: 2025-04-06 11:21:11随机值: 0.11

2.使用Nginx代理WebSocket

代码语言:javascript
复制
location /ws {
    proxy_pass http://192.168.31.121:9000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
proxy_http_version 1.1:强制使用 HTTP 1.1 协议与后端通信。
  • WebSocket 协议依赖 HTTP 1.1 的 Upgrade 机制完成握手。
  • Nginx 默认使用 HTTP 1.0 与后端通信,无法支持协议升级。
proxy_set_header Upgrade $http_upgrade:将客户端的 Upgrade 请求头透传给后端服务器。
  • $http_upgrade 变量捕获客户端请求中的 Upgrade 头(通常为 websocket)。
  • 后端服务器需通过 Upgrade: websocket 头识别 WebSocket 握手请求。
proxy_set_header Connection "upgrade":修改 Connection 请求头为 upgrade,指示后端启用协议升级。
  • Upgrade 头配合,告知后端需要将连接从 HTTP 升级为 WebSocket。

3.验证效果

静态网页的代码把地址修改为使用Nginx代理以后的地址。

这个最核心的就是访问的状态码变成101,如果未有这个则这个WebSocket访问就是失败的。如果你有共有云的机器,在使用控制台登录的时候,就会用到这个WebSocket,因为他们基本上都是通过WebSocket代理到虚拟机的vnc端口。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维小路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • proxy_http_version 1.1:强制使用 HTTP 1.1 协议与后端通信。
  • proxy_set_header Upgrade $http_upgrade:将客户端的 Upgrade 请求头透传给后端服务器。
  • proxy_set_header Connection "upgrade":修改 Connection 请求头为 upgrade,指示后端启用协议升级。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档