Nginx配置Websocket

WebSocket 和HTTP虽然是不同协议,但是两者“握手”方式兼容。通过HTTP升级机制,使用HTTP的Upgrade和Connection协议头的方式可以将连接从HTTP升级为WebSocket。

Websocket 使用 ws 或 wss 的统一资源标志符,类似于 HTTPS,其中 wss 表示在 TLS 之上的 Websocket。如:

ws://example.com/wsapi
wss://secure.example.com/

Websocket 使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket 协议使用 80 端口;运行在 TLS 之上时,默认使用 443 端口。

一个典型的Websocket握手请求如下:

客户端请求:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

服务器回应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/

关键点:

  • Connection 必须设置 Upgrade,表示客户端希望连接升级。

  • Upgrade 字段必须设置 Websocket,表示希望升级到 Websocket 协议。

知识点参考:《HTML5 WebSocket》

一、对wss与nginx代理wss的理解:

1、wss协议实际是websocket +SSL,就是在websocket协议上加入SSL层,类似https(http+SSL)。

2、利用nginx代理wss【通讯原理及流程】

  • 客户端发起wss连接连到nginx

  • nginx将wss协议的数据转换成ws协议数据并转发到Workerman的websocket协议端口

  • Workerman收到数据后做业务逻辑处理

  • Workerman给客户端发送消息时,则是相反的过程,数据经过nginx/转换成wss协议然后发给客户端

二、Nginx配置Websocket参数

示例一:某站点或域名下面代理配置

server {listen       80;server_name  域名;proxy_http_version  1.1;……#启用支持websocket连接的配置proxy_set_header    Upgrade             $http_upgrade;proxy_set_header    Connection          "upgrade";location / {proxy_redirect off;proxy_pass http://myweb_backend;proxy_connect_timeout 60;proxy_read_timeout 600;proxy_send_timeout 600;}}

重要的是这两行,它表明是websocket连接进入的时候,进行一个连接升级将http连接变成websocket的连接。启用支持websocket连接:proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

proxy read timeout 表明连接成功以后等待服务器响应的时候,如果不配置默认为60s;

proxy_http_version 1.1;

表明使用http版本为1.1

示例二:全部站点或全部服务的代理配置

上面的配置将websocket写到某个server里了。实际项目上nginx代理的可能是多个站点,多个服务,这就需要统一设置一下。另外对于低版本nginx的配置不支持"upgrade"参数的情况下可以这样写:

首先在nginx的全局块(一般是http块)里面加上websocket的参数映射

http {include       mime.types;default_type  text/html;charset utf-8;log_format  proxy '$http_x_real_ip - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" $request_time $upstream_response_time';access_log  /dev/stdout proxy;sendfile        on;tcp_nopush      on;tcp_nodelay     on;keepalive_timeout  75;keepalive_requests 1000;client_max_body_size 1020000M;client_body_buffer_size  256k;large_client_header_buffers 4 128k;client_header_buffer_size 32k;server_names_hash_max_size 512;server_names_hash_bucket_size 128;#注意,必须加下面这段websocket的参数映射map $http_upgrade $connection_upgrade {default upgrade;'' close;}include /etc/nginx/conf.d/*.conf;
}

这里重要的是这四行:

注意,必须加下面这段websocket的参数映射

然后在你的server或者location块里面加上这两行即可:

server {listen       80;server_name  域名;proxy_http_version  1.1;……#注意,必须加下面这段websocket的配置proxy_set_header    Upgrade             $http_upgrade;proxy_set_header    Connection          $connection_upgrade;location / {proxy_redirect off;proxy_pass http://myweb_backend;proxy_connect_timeout 60;proxy_read_timeout 600;proxy_send_timeout 600;}}

  • 示例一和示例二配置一种就行。

状态码说明

注意:因为websocket是长连接,请求过程不关闭的所以一般连接状态码是101(请求者已要求服务器切换协议,服务器已确认并准备切换。)

CloseEvent接口的代码只读属性返回WebSocket连接关闭代码,指示服务器关闭连接的原因。

值:一个整数的WebSocket连接关闭范围为1000-4999的代码,指示服务器关闭连接的原因。websocket连接关闭状态码:CloseEvent: code property - Web APIs | MDN

不支持websocket协议现象说明

网页控制台报错现象:

1)现象一:

网页控制台报"WebSocket connection to 'ws://' failed:<无报错信息>"

2)现象二:

网页控制台报"WebSocket connection to 'ws://' failed:Error during WebSocket handshake: Unexpected response code: 400"

3)现象三:网页控制台报"WebSocket connection to 'ws://' failed:The request timed out.

问题原因与处理方法:

1.代理/防火墙对访问端口只开通了http协议,未支持websocket协议。可以将代理/防火墙的7层转发改为4层转发,确认是否为websocket协议/长连接的支持问题。

2.代理nginx未支持websocket协议转发,检查nginx配置文件中的Upgrade和Connection配置。

文章转载自:熊仔其人

原文链接:https://www.cnblogs.com/xiongzaiqiren/p/Nginx_Websocket.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/207033.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能座舱架构与芯片 - (1) 背景篇

一、软件定义汽车 1.1 什么是软件定义汽车 软件定义汽车(Software Defined Vehicles, SDV)的核心思想是&#xff0c;决定未来汽车的是人工智能为核心的软件技术&#xff0c;而不再是汽车的马力大小&#xff0c;是否真皮座椅&#xff0c;机械性能的好坏。软件定义汽车的终极目…

【深度学习】卷积神经网络(CNN)

一、引子————边界检测 我们来看一个最简单的例子&#xff1a;“边界检测&#xff08;edge detection&#xff09;”&#xff0c;假设我们有这样的一张图片&#xff0c;大小88&#xff1a; 图片中的数字代表该位置的像素值&#xff0c;我们知道&#xff0c;像素值越大&#…

在 vscode 中的json文件写注释,不报错的解决办法

打开 vscode 的「设置」&#xff0c;搜索&#xff1a;files: associations&#xff0c;然后添加 *.json jsonc最后

AIGC ChatGPT4总结SQL优化细节操作

数据库SQL优化是一个复杂的过程,它通常涉及到许多不同的技术和方法。以下是一些常用的SQL优化策略: 1. **索引使用**:索引可以极大地加速查询速度。但是,索引并不总是有好处的,因为它们需要额外的空间来存储,并且在插入和更新数据时可能会减慢速度。因此,选择正确的字段…

ILI9225 TFT显示屏16位并口方式驱动

所用屏及资料如后图&#xff1a; ILI9225&#xff0c;176*220&#xff0c;8位或16位并口屏&#xff0c;IM0接GND&#xff0c;电源及背光接3.3v 主控&#xff1a;CH32V307驱动&#xff08;库文件和STM32基本一样&#xff09; 一、源码 ILI9225.c #include "ILI9225.h&quo…

Jmeter性能测试:高并发分布式性能测试

一、为什么要进行分布式性能测试 当进行高并发性能测试的时候&#xff0c;受限于Jmeter工具本身和电脑硬件的原因&#xff0c;无法满足我们对大并发性能测试的要求。 基于这种场景下&#xff0c;我们就需要采用分布式的方式来实现我们高并发的性能测试要求。 二、分布式性能…

学习MySQL先有全局观,细说其发展历程及特点

学习MySQL先有全局观&#xff0c;细说其发展历程及特点 一、枝繁叶茂的MySQL家族1. 发展历程2. 分支版本 二、特点分析1. 常用数据库2. 选型角度及场景 三、三大组成部分四、总结 相信很多同学在接触编程之初&#xff0c;就接触过数据库&#xff0c;而对于其中关系型数据库中的…

使用Java Servlet生成动态二维码

文章目录 引入ZXing库创建QRCodeServlet部署到Servlet容器拓展功能1. 动态生成二维码内容2. 调整二维码尺寸3. 错误修正级别4. 日志输出 结语 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&…

Linux程序之可变参数选项那些事!

一、linux应用程序如何接收参数&#xff1f; 1. argc、argv Linux应用程序执行时&#xff0c;我们往往通过命令行带入参数给程序&#xff0c;比如 ls /dev/ -l 其中参数 /dev/ 、-l都是作为参数传递给命令 ls 应用程序又是如何接收这些参数的&#xff1f; 通常应用程序都…

矩阵知识补充

正交矩阵 定义&#xff1a; 正交矩阵是一种满足 A T A E A^{T}AE ATAE的方阵 正交矩阵具有以下几个重要性质&#xff1a; A的逆等于A的转置&#xff0c;即 A − 1 A T A^{-1}A^{T} A−1AT**A的行列式的绝对值等于1&#xff0c;即 ∣ d e t ( A ) ∣ 1 |det(A)|1 ∣det(A)∣…

Mysql中自增主键是如何工作的

自增主键的特点是当表中每新增一条记录时&#xff0c;主键值会根据自增步长自动叠加&#xff0c;通常会将自增步长设置1&#xff0c;也就是说自增主键值是连续的。那么MySQL自增主键值一定会连续吗&#xff1f;今天这篇文章就来说说这个问题&#xff0c;看看什么情况下自增主键…

Java游戏之飞翔的小鸟

前言 飞翔的小鸟 小游戏 可以作为 java入门阶段的收尾作品 &#xff1b; 需要掌握 面向对象的使用以及了解 多线程&#xff0c;IO流&#xff0c;异常处理&#xff0c;一些java基础等相关知识。一 、游戏分析 1. 分析游戏逻辑 &#xff08;1&#xff09;先让窗口显示出来&#x…