【Nginx笔记02】通过Nginx服务器转发客户端的WebSocket接口到后端服务
这篇文章,主要介绍如何通过Nginx服务器转发客户端的WebSocket接口到后端服务【知识星球】。
目录
一、Nginx配置WebSocket
1.1、Nginx配置内容
1.2、客户端请求地址
1.3、创建WebSocket测试工程
1.4、启动测试
1.5、WebSocket超时问题
1.5.1、设置超时时间
1.5.2、建立心跳机制(推荐)
一、Nginx配置WebSocket
今天在工作中,遇到了一个需求,这个需求大概是前端和后端需要采用WebSocket方式来进行通信,因为是WebSocket接口,客户端需要知道通讯的接口地址,WebSocket接口的地址格式是:【ws://ip:port/xxx/yyy】,其中ip和port是后端服务提供的,/xxx/yyy是后端服务中提供的具体WebSocket接口地址。
这里就遇到了一个问题,后端服务不止一台,有可能启动两台服务,采用不同的端口来区分,客户端就不知道应该填写哪个port端口,后面想到的解决方案是通过Nginx服务器进行WebSocket接口的转发,让Nginx来决定调用哪个WebSocket接口,而客户端只需要和Nginx服务器进行交互即可。
案例下载地址:【https://download.csdn.net/download/qq_39826207/88883292】
1.1、Nginx配置内容
为了让Nginx能够代理转发WebSocket接口,我们需要针对WebSocket接口地址配置一个location信息,使用proxy_pass转发到具体的后端接口服务。在nginx.conf配置文件中,添加如下配置内容:
#user nobody;
worker_processes 1;error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;pid logs/nginx.pid;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;#gzip on;keepalive_timeout 65;# 定义变量,兼容HTTP和WebSocket两种请求协议map $http_upgrade $connection_upgrade {default keep-alive; # 默认 keep-alive,表示HTTP协议。'websocket' upgrade; # 若是 websocket 请求,则升级协议 upgrade。}server {listen 9990;# 这里写后端接口服务提供的WebSocket完整地址# 例如:我这里提供的WebSocket接口地址是 /demo/websocketlocation /demo/websocket {proxy_pass http://127.0.0.1:8880; # 转发到后端接口proxy_read_timeout 20s; # 设置超时时间,默认是60sproxy_http_version 1.1;proxy_set_header Host $host; # 这个配置不要漏了,必须要proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;}}
}
注意:上面配置中,有两个内容需要配置,见下图中的红色框框内容:
1.2、客户端请求地址
浏览器客户端向【ws://127.0.0.1:9990/demo/websocket】建立连接,当Nginx服务器接收到之后,就会匹配上location的定义的规则,此时会将【ws://127.0.0.1:9990/demo/websocket】地址转发到【ws://127.0.0.1:8880/demo/websocket】这个地址,这就完成了WebSocket接口的转发功能。
- 注意点:location后面定义的地址要和后端接口提供的WebSocket地址一模一样,不能采用模糊匹配,否则转发不了WebSocket接口。
刚开始我是参考网上的一些配置,location后面之间使用的【/websocket】,发现怎么也转发不了,后面测试了才知道,网上那些配置,他们对应后端WebSocket接口地址就是【/websocket】,所以他们可以转发成功。我的后端接口地址是【/demo/websocket】,location配置成【/websocket】肯定是不行的。
1.3、创建WebSocket测试工程
为了模拟Nginx能否成功转发WebSocket接口,这里我本地创建了一个WebSocket的测试工程,如下所示:
1.4、启动测试
- 第一步:启动本地的WebSocket测试工程。
- 第二步:启动Nginx服务。
- 第三步:找一个在线的WebSocket测试工具,查看【ws://127.0.0.1:9990/demo/websocket】是否可以连接成功。
这里我使用的是【https://wstool.js.org/】WebSocket在线测试工具,如下图所示:
从上图中,我们可以知道,WebSocket接口服务对外提供的是8880端口,客户端连接的是9990端口,端口不一致的情况下,WebSocket依然连接成功了,这说明我们配置的Nginx转发功能成功啦。
1.5、WebSocket超时问题
Nginx配置里面,默认情况下,WebSocket接口的超时时间是60s,如果在60s里面,都没有使用WebSocket进行发送消息,那么此时就会断开WebSocket连接。
这种情况下,我们客户端如果再次发送消息,就会抛出异常,因为WebSocket连接已经断开,无法发送消息,那么要如何解决这个问题呢???
针对上面的问题,可以有下面两种解决方案:
1.5.1、设置超时时间
Nginx提供了一个【proxy_read_timeout】属性,该属性可以用于设置WebSocket接口的超时时间,默认是60s,那么我们就可以设置成5分钟,配置内容如下所示:
# 这里写后端接口服务提供的WebSocket完整地址
# 例如:我这里提供的WebSocket接口地址是 /demo/websocket
location /demo/websocket {proxy_pass http://127.0.0.1:8880; # 转发到后端接口proxy_read_timeout 300s; # 设置超时时间,默认是60sproxy_http_version 1.1;proxy_set_header Host $host; # 这个配置不要漏了,必须要proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;
}
注意:这种配置不推荐使用,因为proxy_read_timeout属性治标不治本,超过5分钟还是没有通信怎么办呢???不依然会断开连接吗。
1.5.2、建立心跳机制(推荐)
最好的机制是让客户端和服务器之间,每隔一段时间进行一次心跳通信,例如:让客户端每隔30s向服务器发送一次消息,客户端有发送消息给服务端,那么Nginx就知道当前这个WebSocket连接是有用的,就不会将其断开。
注意:假设超时时间是60s,经过30s没有通信,按理说,再过30s没有通信,就会断开连接,但是如果客户端发送一条消息给服务端,此时,超时时间就会重新计算,超时时间又会变成60s。
到此,Nginx服务器转发WebSocket接口就配置完成啦。
综上,这篇文章结束了,主要介绍如何通过Nginx服务器转发客户端的WebSocket接口到后端服务。
相关文章:

【Nginx笔记02】通过Nginx服务器转发客户端的WebSocket接口到后端服务
这篇文章,主要介绍如何通过Nginx服务器转发客户端的WebSocket接口到后端服务【知识星球】。 目录 一、Nginx配置WebSocket 1.1、Nginx配置内容 1.2、客户端请求地址 1.3、创建WebSocket测试工程 1.4、启动测试 1.5、WebSocket超时问题 1.5.1、设置超时时间 …...

关于高德地图及其APP获取地图数据的研究
刚过完春节没几天,有个客户提出要获取高德地图的数据。 我看了下,回复说:这不是很简单嘛,高德有公开的开放平台,有足够的API支持用户获取数据,开发自己基于高德数据库的应用。 客户回复说:他的要…...
【Python入门教程】Python实现鸡兔同笼
今天跟大家分享一下很久之前自己做的鸡兔同笼求解问题的小游戏,使用公式和基本的判断语句即可实现,可以用来当练手或者消磨时间用。 大家在编代码的时候最重要就是先理清逻辑思路,例如应该套几层循环、分几个模块等等。然后在编码时可以先随意…...

微信小程序,h5端自适应登陆方式
微信小程序端只显示登陆(获取opid),h5端显示通过账户密码登陆 例如: 通过下面的变量控制: const isWeixin ref(false); // #ifdef MP-WEIXIN isWeixin.value true; // #endif...
物体检测-系列教程20:YOLOV5 源码解析10 (Model类前向传播、forward_once函数、_initialize_biases函数)
😎😎😎物体检测-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 14、Model类 14.2 前向传播 def forward(self, x, augmentFalse, profileFalse):if augm…...

贪吃蛇(C语言)步骤讲解
一:文章大概 使用C语言在windows环境的控制台中模拟实现经典小游戏 实现基本功能: 1.贪吃蛇地图绘制 2.蛇吃食物的功能(上,下,左,右方向控制蛇的动作) 3.蛇撞墙死亡 4.计算得分 5.蛇身加…...

MySQL 数据库表设计和优化
一、数据结构设计 正确的数据结构设计对数据库的性能是非常重要的。 在设计数据表时,尽量遵循一下几点: 将数据分解为合适的表,每个表都应该有清晰定义的目的,避免将过多的数据存储在单个表中。使用适当的数据类型来存储数据&…...

JavaScript进阶-高阶技巧
文章目录 高阶技巧深浅拷贝浅拷贝深拷贝 异常处理throw抛异常try/caych捕获异常debugger 处理thisthis指向改变this 性能优化防抖节流 高阶技巧 深浅拷贝 只针对引用类型 浅拷贝 拷贝对象后,里面的属性值是简单数据类型直接拷贝值,如果属性值是引用数…...
C语言中“#“和“##“的用法
1. 前言 # :把宏参数变为一个字符串, ##:把两个宏参数贴合在一起. 2. 一般用法 #include<stdio.h> #define toString(str) #str //转字符串 #define conStr(a,b) (a##b)//连接 int main() { printf(toString(12345)): //输出字符串&q…...
Linux命令-clock命令(用于调整 RTC 时间)
说明 clock命令用于调整 RTC 时间。 RTC 是电脑内建的硬件时间,执行这项指令可以显示现在时刻,调整硬件时钟的时间,将系统时间设成与硬件时钟之时间一致,或是把系统时间回存到硬件时钟。 语法 clock [--adjust][--debug][--dir…...
编程笔记 Golang基础 045 math包
编程笔记 Golang基础 045 math包 一、math包主要功能常量:函数:数值运算:三角函数:对数函数:随机数相关: 二、示例代码一三、示例代码二小结 Go 语言的标准库 math 提供了一系列基础数学函数和常量…...

[Java 探索者之路] 一个大厂都在用的分布式任务调度平台
分布式任务调度平台是一种能够在分布式计算环境中调度和管理任务的系统,在此环境下,各个任务可以在独立的节点上运行。它有助于提升资源利用率,增强系统扩展性以及提高系统对错误的容忍度。 文章目录 1. 分布式任务调度平台1. 基本概念1.1 任…...

基于JAVA springboot+mybatis智慧生活分享平台设计和实现
基于JAVA springbootmybatis智慧生活分享平台设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末…...

详细了解C++中的namespace命名空间
键盘敲烂,月薪过万,同学们,加油呀! 目录 键盘敲烂,月薪过万,同学们,加油呀! 一、命名空间的理解 二、::作用域运算符 三、命名空间(namespace&…...

#WEB前端(HTML属性)
1.实验:a,img 2.IDE:VSCODE 3.记录: a: href插入超链接 默认情况下在本窗口打开链接, target可以设置打开的窗口,parent在父窗口打开,blank新开串口打开,top在顶层串口打开,self为默认在本窗口打开 img: 插入图片 可以插…...
LeetCode---【和的操作】
目录 两数之和我的答案在b站up那里学到的【然后自己复写】 和为 K 的子数组在b站up那里学到的【然后自己复写】 三数之和在b站up那里学到的【然后自己复写】 两数相加【链表】我的半路答案:没有看到是链表在b站up那里学到的【复写失败后整理】 两数之和 我的答案 …...

Docker容器与虚拟化技术:OpenEuler 使用 docker-compose 部署 LNMP
目录 一、实验 1.环境 2.OpenEuler 部署 docker-compose 3.docker-compose 部署 LNMP 二、问题 1.ntpdate未找到命令 2.timedatectl 如何设置时区与时间同步 3.php网页显示时区不对 一、实验 1.环境 (1)主机 表1 主机 系统架构版本IP备注Lin…...

13-微服务初探-自研微服务框架
微服务初探 1. 架构变迁之路 1.1 单体架构 互联网早期,一般的网站应用流量较小,只需要一个应用,将所有的功能代码都部署在一起就可以,这样可以减少开发,部署和维护的成本。 比如说一个电商系统,里面包含…...

LeetCode——二叉树(Java)
二叉树 简介[简单] 144. 二叉树的前序遍历、94. 二叉树的中序遍历、145. 二叉树的后序遍历二叉树层序遍历[中等] 102. 二叉树的层序遍历[中等] 107. 二叉树的层序遍历 II[中等] 199. 二叉树的右视图[简单] 637. 二叉树的层平均值[中等] 429. N 叉树的层序遍历[中等] 515. 在每个…...

LDR6328芯片:智能家居时代的小家电充电革新者
在当今的智能家居时代,小家电的供电方式正变得越来越智能化和高效化。 利用PD(Power Delivery)芯片进行诱骗取电,为后端小家电提供稳定电压的技术,正逐渐成为行业的新宠。在这一领域,LDR6328芯片以其出色的…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...