spring中使用netty-socketio部署到服务器(SSL、nginx转发)
spring中使用netty-socketio部署到服务器(SSL、nginx转发)
本文实现前端socket.io-client连接后端netty-socketio,并且部署到服务器上的示例,以及说明一些实现过程中可能遇到的错误。
socketio默认基于的路径是/socket.io
传输方式有三种分别是:
1、polling
polling是最传统的基于http的方式、兼容性强,定期向服务端循环是否还保持链接,这种方式也是websocket无法使用时的降级选择。
2、websocket
全双工通信、维持客户端和服务端之间的持久连接,它比轮询更有效,因为它消除了HTTP请求/响应周期。浏览器基本上都支持。
3、webtransport
基于HTTP/3和QUIC的较新的传输协议、提供低延迟、双向、多路通信、支持可靠(类似tcp)和不可靠(类似udp)的数据传输、专为高性能应用程序,如游戏和视频流、对比WebSockets有更好的拥塞控制和连接迁移,但它还没有像WebSockets那样被广泛支持。
如果你选择polling模式,可以使用extraHeaders,因为它基于http,但是使用websocket模式时,extraHeaders无效,但是也有替换方案,websocket可以把参数传到url里面中。
坑①:用polling模式本地连接正常,但是部署到服务器出现PollingTransport:167 - <sessionId> is not registered. Closing connection
,一致没搞懂为什么。
由于坑①,前端指定使用websocket模式连接,假设后端netty-socketio开放9000端口,首先编写一个socket实例
const socket = *ref*<Socket | null>(null);
socket.value = io("http://127.0.0.1:9000",{path: "/socket.io",// 默认是socket.iowithCredentials: true,// 允许跨域transports: ["websocket"],// 指定传输模式}
);
path路径默认是socket.io,当然可以后端通过配置修改
后端基于spring编写一个bean
@Bean
public SocketIOServer socketIOServer() {Configuration config = new Configuration();config.setPort(9000);config.setHostname("0.0.0.0");config.setJsonSupport(new JacksonJsonSupport());config.setExceptionListener(new DefaultExceptionListener());config.setHttpCompression(false);config.setWebsocketCompression(false);config.setKeyStore(getCertJks());// 如果你有证书这样配置config.setKeyStorePassword("8di1g1a8");// 证书密码,没有可以删除这两行return new SocketIOServer(config);
}
坑②:如果你使用的是polling模式,传了请求头,那么后端必须在配置中允许该请求头,否则接收不到
config.setAllowHeaders(tokenName);
再写个启动服务类
@Component
@Slf4j
public class SocketIOEventListener {private final SocketIOServer socketIOServer;private final WebSocketService webSocketService;@Autowiredpublic SocketIOEventListener(SocketIOServer socketIOServer, WebSocketService webSocketService) {this.socketIOServer = socketIOServer;this.webSocketService = webSocketService;}@PostConstructprivate void init() {socketIOServer.addConnectListener(client -> {webSocketService.connect(client);});socketIOServer.addDisconnectListener(client -> {webSocketService.disconnect(client);});socketIOServer.start();}@PreDestroyprivate void destroy() {// 关闭服务器socketIOServer.stop();}
}
WebSocketService.class如下
@Service
@Slf4j
@RequiredArgsConstructor
public class WebSocketService {public void connect(SocketIOClient client) {//....连接成功}public void disconnect(SocketIOClient client) {//....断开成功}
}
前端本地测试成功连通,之后尝试部署服务器,我有一个域名xxx.cn服务器,其中nginx在这个服务器上,我的后端服务在另一个服务器上,我需要使用xxx.cn/socket把服务转发到另一个后端服务器上去,于是编写nginx配置
location /socket{proxy_pass http://120.11.111.11:9000;# 随便编的IPrewrite "^/socket/(.*)$" /$1 break;
}
因为要通过socket转发,前端socket我这样写
socket.value = io("https://www.guetzjb.cn/socket",{path: "/socket/socket.io",withCredentials: true,transports: ["websocket"],}
);
看起来很合理,结果现实马上就能给你当头一棒
后端一连接上就立马断开了,秒断
5247fb7d-804b-403f-8ca7-84d876fb017c连接成功,当前在线人数1
5247fb7d-804b-403f-8ca7-84d876fb017c断开成功,当前在线人数0
前端socket数据是这样的
0{"sid":"5247fb7d-804b-403f-8ca7-84d876fb017c","upgrades":[],"pingInterval":25000,"pingTimeout":60000}
40/socket
44/draw-socket,"Invalid namespace"
收集到关键词Invalid namespace,经过服务器得靠socket转发,这是识别成namespace了?
正确姿势👇
修改启动类新增namespace
@Component
@Slf4j
public class SocketIOEventListener {//........@PostConstructprivate void init() {//其他代码SocketIONamespace ns = socketIOServer.addNamespace("/socket");// 必须斜杠开头//其他代码}//.........
}
注意新增命名空间必须是 / 开头,否则无效,默认明明空间就是/,但是加入你这样做
SocketIONamespace ns = socketIOServer.addNamespace("/");
ns.addConnectListener(client -> {// 无效做法,连不上
});
坑③:上面这也连不上,默认命名空间必须使用socketIOServer.addConnectListener
当然,使用/socket就可以正常连接了
此时本地代码和线上代码都使用一个namespace就可以了
socket.value = io("http://127.0.0.1:9000/socket",//使用socket namespace{path: "/socket.io",withCredentials: true,transports: ["websocket"],}
);
部署到线上需要通过socket转发
所以线上的path需要这样
socket.value = io("http://127.0.0.1:9000/socket",//使用socket namespace{path: "/socket/socket.io",withCredentials: true,transports: ["websocket"],}
);
配置上nginx
location /socket/socket.io{proxy_pass http://120.26.103.82:9000;rewrite "^/socket/(.*)$" /$1 break;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";
}
socket.io需要升级为长链接,原先的/socket正常转发
再次部署
本地和线上都跑起来啦!
测试是不用设置setKeyStore的,当然你也可以设置上👇
@Bean
public SocketIOServer socketIOServer() {Configuration config = new Configuration();// 其他配置
// config.setKeyStore(getCertJks());
// config.setKeyStorePassword("zfs2k32p");return new SocketIOServer(config);
}private InputStream getCertJks() {ClassPathResource classPathResource = new ClassPathResource("xxxx.cn.jks");return classPathResource.getStream();
}
相关文章:
spring中使用netty-socketio部署到服务器(SSL、nginx转发)
spring中使用netty-socketio部署到服务器(SSL、nginx转发) 本文实现前端socket.io-client连接后端netty-socketio,并且部署到服务器上的示例,以及说明一些实现过程中可能遇到的错误。 socketio默认基于的路径是/socket.io 传输…...
qt.tlsbackend.ossl: Failed to load libssl/libcrypto.
我的环境是windows,QT6.3.2(msvc2019_64/mingw_64) 出错原因 QT没有正确加载OpenSSL。 解决过程 1、确保安装的有openssl。 文章结尾有个注意,是其他方式安装过openssl,环境变量有,但是QT找不到的问题。…...
【Python爬虫基础篇】--3.cookie和session
目录 1.cookie 1.1.定义 1.2.参数 1.3.分类 2.session 3.使用cookie登录微博 4.使用session登录 1.cookie 由于http是一个无状态的协议,请求与请求之间无法相互传递或者记录一些信息,cookie和session正是为了解决这个问题而产生。 例子࿱…...
uView的u-modal不显示问题
问题分析:在项目中,其他页面显示正常,在这个页面显示不正常。 问题解决: 一般的原因,诸如层级遮挡控制器true后,被其他逻辑又改为了false最可恨的一个原因 :showshow被编辑器的提示功能误写成了v-modal&qu…...
联易融科技:以科技赋能驱动经营反转与价值重估
行业去重周期下,轻量化发展成破局关键。当前,供应链金融行业正经历从"规模扩张"到"价值深耕"的转型期,降本增效、轻资产运营成为行业共识。联易融公告表示,截至2024年末,公司现金储备高达51亿元,显示出财务状况健康良好,流动资金持续充裕。 董…...
Office文档图片批量提取工具
Office.Files.Images 是一款专注于从 Word、Excel、PPT 等 Office 文档中批量提取图片的轻量级工具,支持 .docx、.xlsx、.pptx 格式文件。该软件体积仅 343KB,无需安装即可运行,通过拖拽操作实现快速解析与导出,尤其适合需批量…...
Python 设计模式:回调模式
1. 什么是回调函数? 回调函数是指作为参数传递给另一个函数的函数。当这个函数执行到某个特定的点时,它会调用这个回调函数。回调函数通常用于处理异步操作、事件处理或在某些条件下执行特定的操作。 回调函数的特点: 作为参数传递&#x…...
DCDC芯片,boost升压电路设计,MT3608 芯片深度解析:从架构到设计的全维度技术手册
一、硬件架构解析:电流模式升压 converter 的核心设计 (一)电路拓扑与核心组件 MT3608 采用恒定频率峰值电流模式升压(Boost)转换器架构,核心由以下模块构成: 集成功率 MOSFET 内置 80mΩ 导通电阻的 N 沟道 MOSFET,漏极(Drain)对应引脚 SW,源极(Source)内部接…...
大数据学习(112)-HIVE中的窗口函数
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...
Hive学习
一、Hive 核心原理 1. Hive 架构与执行流程 Hive 是基于 Hadoop 的数据仓库工具,将 SQL 转化为分布式计算任务(MapReduce/Tez/Spark),核心组件如下: 元数据存储(Metastore):存储表…...
前端开发核心知识详解:Vue2、JavaScript 与 CSS
一、Vue2 核心知识点 1. Vue2 的双向绑定原理 Vue2 实现双向绑定主要依赖数据劫持与发布 - 订阅者模式。 利用Object.defineProperty方法对数据对象的属性进行劫持,为每个属性定义getter和setter。getter用于收集依赖,当视图中使用到该属性时…...
仅追加KV数据库
仅追加KV数据库 6.1 我们将要做什么 在本章中,我们将创建一个基于文件的键值存储(KV Store),其核心是一个写时复制(Copy-on-Write, CoW)B 树。这种设计的目标是实现数据的持久性和原子性。 1. 设计概述 …...
【Java面试笔记:基础】8.对比Vector、ArrayList、LinkedList有何区别?
在Java中,Vector、ArrayList和LinkedList均实现了List接口,但它们在线程安全、数据结构、性能特性及应用场景上存在显著差异。 1. Vector、ArrayList 和 LinkedList 的区别 Vector: 线程安全:Vector 是线程安全的动态数组&#…...
Git分支管理方案
成都众望智慧有限公司Git分支管理方案 采用 轻量级Git Flow 敏捷版本控制策略,在保证稳定性的同时提升开发效率。以下是优化后的方案: 1. 精简分支模型(相比6-8人团队减少分支层级) 分支类型作用生命周期devops生产环境代码&am…...
SQL Tuning Advisor
什么是SQL Tuning Advisor STA可以用来优化那些已经被发现的高负载SQL. 默认情况下, Oracle数据库在自动维护窗口中自动认证那些有问题的SQL并且执行优化建议,找寻提升高负载SQL执行计划性能的方法. ** 如何查看自动优化维护窗口产生的报告? ** SQL> set ser…...
联易融出席深圳链主企业供应链金融座谈会,加速对接票交所系统
近日,深圳市委金融办组织召开全市链主企业供应链金融高质量发展座谈会。联易融作为供应链金融企业代表,与虾皮信息科技、电子元器件和集成电路国际交易中心等代表性机构以及行业协会、金融机构参加了会议。 发展供应链金融是破解中小微企业融资难、融资…...
【前端记事】关于electron的入门使用
electron入门使用 背景how to start第一步 创建一个vite-vue3项目第二步 装各种依赖第三步 配置vite.config.jspackage.jsonelectron入口 启动重写关闭、隐藏、最大化最小化 背景 最近对electron比较感兴趣,折腾一段时间后有了点眉目,记录一下 how to …...
Qt绘制可选择范围的日历
【日历控件设计】 #include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QCalendarWidget> #include <QHBoxLayout> #include <QSpinBox> #include <QPushButton> #include <QLabel> #include <Q…...
Pycharm(十五)面向对象程序设计基础
目录 一、定义类及使用类的成员 二、self关键字介绍 三、在类内部调用类中的函数 class 类名: 属性(类似于定义变量) 行为(类似于定义函数,只不过第一个形参要写self) 一、面向对象基本概述 属性&…...
【C++游戏引擎开发】第21篇:基于物理渲染(PBR)——统计学解构材质与光影
引言 宏观现象:人眼观察到的材质表面特性(如金属的高光锐利、石膏的漫反射柔和),本质上是微观结构对光线的统计平均结果。 微观真相:任何看似平整的表面在放大后都呈现崎岖的微观几何。每个微表面(Microfacet)均为完美镜面,但大量微表面以不同朝向分布时,宏观上会表…...
flutter_slidable 插件使用
简介 flutter_slidable 是一个用于创建可滑动列表项的 Flutter 插件,它允许用户通过滑动来显示隐藏的操作按钮,比如删除、分享等功能。 安装 在 pubspec.yaml 中添加依赖(并运行 flutter pub get): dependencies:fl…...
[论文阅读]ConfusedPilot: Confused Deputy Risks in RAG-based LLMs
ConfusedPilot: Confused Deputy Risks in RAG-based LLMs [2408.04870] ConfusedPilot: Confused Deputy Risks in RAG-based LLMs DEFCON AI Village 2024 文章是针对Copilot这样一个RAG服务提供平台的攻击 在企业环境中整合人工智能工具(如 RAG)会…...
诠视科技MR眼镜如何使用头瞄点和UGUI交互
诠视科技MR眼镜如何使用头瞄点和UGUI交互 要实现头瞄点计算单元确认键操作UGUI,最快捷的方式,右键直接添加XvHeadGazeInputController。 添加以后会自动生成XvHeadGazeInputController到Head节点下面去。 重要的几个参数讲解: scaleFactor:…...
数据赋能(204)——原则与原理——原理方法
原理更多地关注事物本身的客观规律,而原则侧重于指导人们的行为和决策。原则与原理是两个常常被提及,但有所区别的概念。原则和原理在各个领域中都发挥着重要的作用。 原理概念 原理,则通常指的是自然科学和社会科学中具有普遍意义的基本规…...
代码随想录算法训练营第五十六天 | 108.冗余连接 109.冗余连接II
108.冗余连接 题目链接:108. 冗余的边 文章讲解:代码随想录 思路: 题目说是无向图,返回一条可以删去的边,使得结果图是一个有着N个节点的树,如果有多个答案,则返回二维数组中最后出现的边。 …...
Git入门
一、Git 基础概念 1. 版本控制系统分类 本地版本控制:如RCS,仅在本机保存历史版本集中式版本控制:如SVN,单一中央服务器管理代码分布式版本控制:如Git,每个开发者都有完整的仓库副本 2. Git 核心概念 概…...
5G + 物联网:智能世界的催化剂,如何用Python打造下一代IoT应用?
5G 物联网:智能世界的催化剂,如何用Python打造下一代IoT应用? 在数字化时代,物联网(IoT) 已成为智能产业的关键技术。从智能家居到智慧城市,再到工业4.0,我们的世界正在变得越来越…...
从单点突破到链式攻击:XSS 的渗透全路径解析
在网络安全领域,跨站脚本攻击(Cross-Site Scripting,简称 XSS)早已不是新鲜话题。然而,随着网络技术的迭代与应用场景的复杂化,攻击者不再满足于单一的 XSS 漏洞利用,而是将 XSS 与其他安全漏洞…...
spark和hadoop的对比和联系
一、Apache Hadoop 简介 Hadoop是一个由Apache基金会开发的开源分布式计算平台。它主要由Hadoop分布式文件系统(HDFS)和MapReduce计算框架组成。HDFS是为大规模数据存储而设计的,它将文件分割成多个数据块(block)&…...
【Vue3 / TypeScript】 项目兼容低版本浏览器的全面指南
在当今前端开发领域,Vue3 和 TypeScript 已成为主流技术栈。然而,随着 JavaScript 语言的快速演进,许多现代特性在低版本浏览器中无法运行。本文将详细介绍如何使 Vue3 TypeScript 项目完美兼容 IE11 等低版本浏览器。 一、理解兼容性挑战 …...
从零开始搭建你的个人博客:使用 GitHub Pages 免费部署静态网站
🌐 从零开始搭建你的个人博客:使用 GitHub Pages 免费部署静态网站 在互联网时代,拥有一个属于自己的网站不仅是一种展示方式,更是一种技术能力的体现。今天我们将一步步学习如何通过 GitHub Pages 搭建一个免费的个人博客或简历…...
java 设计模式 原型模式
简介 原型模式(Prototype Pattern) 是一种创建型设计模式,它通过复制现有对象来生成新对象,而不是通过 new 关键字创建。核心思想是减少对象创建的开销,尤其是当对象初始化过程复杂或代价较高时。 原型模式的核心实现…...
分别配置Github,Gitee的SSH链接
文章目录 前言一、为第二个账号生成新的密钥对二、 配置 SSH config 文件1.引入库使用 Host 别名进行 clone/push/pull注意扩展 前言 之前已经在电脑配置过Github一个仓库ssh链接,今天想配一个Gitee仓库的ssh链接。运行 ssh-keygen -t rsa提示已经存在,…...
从零开始搭建Django博客②--Django的服务器内容搭建
本文主要在Ubuntu环境上搭建,为便于研究理解,采用SSH连接在虚拟机里的ubuntu-24.04.2-desktop系统搭建,当涉及一些文件操作部分便于通过桌面化进行理解,通过Nginx代理绑定域名,对外发布。 此为从零开始搭建Django博客…...
如何用python脚本读取本地excel表格Workbook.xlsx将里面B2:B8内容,发给本地ollama大模型改写内容后写入对应C2:C8?
环境: python3.10 Win10专业版 ollama 火山引擎 影刀 问题描述: 如何用python脚本读取本地excel表格Workbook.xlsx将里面B2:B8内容,发给本地ollama大模型改写内容后写入对应C2:C8? 解决方案: 1.制作一个python脚本如下: import openpyxl import requests import…...
webpack详细打包配置,包含性能优化、资源处理...
以下是一个详细的 Webpack 5 配置示例,包含常见资源处理和性能优化方案: const path require(path); const webpack require(webpack); const { BundleAnalyzerPlugin } require(webpack-bundle-analyzer); const TerserPlugin require(terser-webp…...
MYSQL的binlog
用于备份恢复和主从复制 binlog 有 3 种格式类型,分别是 STATEMENT(默认格式)、ROW、 MIXED: STATEMENT:每一条修改数据的 SQL 都会被记录到 binlog 中(相当于记录了逻辑操作,所以针对这种格式…...
Saliency Driven Perceptual Image Compression阅读
2021 WACV 创新点 常用的评估指标如MS-SSIM和PSNR不足以判断压缩技术的性能,它们与人类对相似性的感知不一致(2和3的MS-SSIM更高,但文字反而没那么清晰)。 考虑显著区域的压缩(a)将更多的比特分配给显著区域(b&#…...
【C++ 类和数据抽象】构造函数
目录 一、构造函数的基本概念 1.1 构造函数核心特性 1.2 构造函数的作用 1.3 构造函数类型体系 二、构造函数的类型 2.1 默认构造函数 2.2 带参数的构造函数 2.3 拷贝构造函数 2.4 移动构造函数(C11 及以后) 三、初始化关键技术 3.1 成员初始…...
kotlin的kmp编程中遇到Unresolved reference ‘java‘问题
解决办法 打开 File → Project Structure → Project 确保 Project SDK 是 与你的 jvmToolchain 保持一致 如果没有,点击右上角 Add SDK 添加 JDK 路径 同步Sync 然后就正常了。 package org.example.projectimport androidx.compose.animation.AnimatedVi…...
鸿蒙Flutter仓库停止更新?
停止更新 熟悉 Flutter 鸿蒙开发的小伙伴应该知道,Flutter 3.7.12 鸿蒙化 SDK 已经在开源鸿蒙社区发布快一年了, Flutter 3.22.x 的鸿蒙化适配一直由鸿蒙突击队仓库提供,最近有小伙伴反馈已经 2 个多月没有停止更新了,不少人以为停…...
【Ultralytics 使用yolo12 读取tiff 数据异常解决】
Ultralytics 使用yolo12 读取tiff 数据解决 Ultralytics 使用yolo12 读取tiff 数据异常解决 Ultralytics 使用yolo12 读取tiff 数据异常解决 Lib\site-packages\ultralytics\utils\patches.py def imread(filename: str, flags: int cv2.IMREAD_COLOR):"""Read…...
画布交互系统深度优化:从动态缩放、小地图到拖拽同步的全链路实现方案
画布交互系统深度优化:从动态缩放、小地图到拖拽同步的全链路实现方案 在可视化画布系统开发中,高效的交互体验与稳定的性能表现是核心挑战。本文针对复杂场景下的五大核心需求,提供完整的技术实现方案,涵盖鼠标中心缩放、节点尺寸…...
GTS-400 系列运动控制器板(七)----修改限位开关触发电平
运动控制器函数库的使用 运动控制器驱动程序、dll 文件、例程、Demo 等相关文件请通过固高科技官网下载,网 址为:www.googoltech.com.cn/pro_view-3.html 1 Windows 系统下动态链接库的使用 在 Windows 系统下使用运动控制器,首先要安装驱动程序。在安装前需要提前下载…...
学习前端(前端技术更新较快,需持续关注技术更新)
目录 1. 基础三件套 1.1 HTML 1.2 CSS 1.3 JavaScript 2. 前端框架 2.1 React 2.2 Vue 2.3 Angular 3. 工程化工具 3.1 构建工具 3.2 代码质量 4. 网络和安全 4.1 HTTP/HTTPS 4.2 性能优化 5. 前沿技术 5.1 TypeScript 5.2 WebAssembly 5.3 微前端 5.4 可视…...
视频转换为MP4格式,小白工具批量转换,在线操作,简单快捷,超实用
小白工具https://www.xiaobaitool.net/videos/convert-to-mp4/ 是一款适合在线将视频转换为MP4格式的工具,尤其适合希望快速转换且无需下载安装软件的用户。以下是对该工具的详细推荐及使用建议: 一、工具特点 在线操作,无需下载 用户只需通…...
PDF处理控件Aspose.PDF指南:使用 Python 将 EPUB 转换为 PDF
EPUB是一种流行的电子书格式,用于可重排内容,而PDF则广泛用于固定版式文档,非常适合共享和打印。如果您想使用 Python 将 EPUB 转换为 PDF,Aspose.PDF for Python 提供了一个简单可靠的解决方案。在本教程中,我们将向您…...
超级扩音器手机版:随时随地,大声说话
在日常生活中,我们常常会遇到手机音量太小的问题,尤其是在嘈杂的环境中,如KTV、派对或户外活动时,手机自带的音量往往难以满足需求。今天,我们要介绍的 超级扩音器手机版,就是这样一款由上海聚告德业文化发…...
Jenkins的地位和作用
所处位置 Jenkins 是一款开源的自动化服务器,广泛应用于软件开发和测试流程中,主要用于实现持续集成(CI)和持续部署(CD)。它在开发和测试中的位置和作用可以从以下几个方面来理解: 1. 在开发和测…...
NumPy进阶:广播机制、高级索引与通用函数详解
目录 一、广播机制:不同形状数组间的运算 1. 概念 2. 广播规则 3. 实例 二、高级索引:布尔索引与花式索引 1. 布尔索引 (1)创建布尔索引 (2)布尔索引的应用 2. 花式索引 (1࿰…...