Tio-Boot 集成 Spring Boot 实现即时通讯功能全解析
Tio-Boot 集成 Spring Boot 实现即时通讯功能全解析(详细版)
一、Tio-Boot 简介
Tio-Boot 是基于 Tio 框架的 Spring Boot Starter 扩展,提供高性能、低延迟的网络通信能力,支持 TCP/UDP 协议及 WebSocket 协议,适用于即时通讯、物联网等场景。其核心优势包括:
- 高性能:基于 Java NIO 实现非阻塞通信
- 易扩展:支持自定义协议和集群扩展
- 简化配置:通过自动配置减少冗余代码
二、项目启动配置
1. 添加依赖
在 pom.xml 中引入 Tio-Boot 依赖(版本 3.6.0.v20200315-RELEASE):
<dependencies><dependency><groupId>org.tio</groupId><artifactId>tio-core-spring-boot-starter</artifactId><version>3.6.0.v20200315-RELEASE</version></dependency><dependency><groupId>org.tio</groupId><artifactId>tio-websocket-spring-boot-starter</artifactId><version>3.6.0.v20200315-RELEASE</version></dependency>
</dependencies>
2. 配置文件 application.yml
server:port: 8080tio:websocket:server:ip: 127.0.0.1heartbeat-timeout: 600000
3. 启动类配置
在 Spring Boot 主类添加 @EnableTioWebSocketServer 注解:
@SpringBootApplication
@EnableTioWebSocketServer
public class TioChatApplication {public static void main(String[] args) {SpringApplication.run(TioChatApplication.class, args);}
}
@Configuration
public class TioManualConfig {@Value("${tio.websocket.server.port:9326}")private int websocketPort;@Bean(initMethod = "start")public WsServerStarter wsServerStarter() throws IOException {return new WsServerStarter(websocketPort, new TioWebSocket());}
}
三、核心功能实现
1. 消息处理器(Handler)
创建 ChatServerAioHandler 处理消息收发:
@Component
@TioWebSocketMsgHandler
public class ChatServerAioHandler implements IWsMsgHandler {private static final String CHARSET = "UTF-8";@Overridepublic HttpResponse handshake(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) {String userId = httpRequest.getParam("uid");if (StrUtil.isBlank(userId)) {httpResponse.setStatus(HttpResponseStatus.C401);return httpResponse;}// 绑定用户到默认群组Tio.bindGroup(channelContext, "default_group");Tio.bindUser(channelContext, userId);return httpResponse;}@Overridepublic void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) {System.out.println("用户 " + channelContext.getToken() + " 已连接");}@Overridepublic Object onText(WsRequest wsRequest, String message, ChannelContext channelContext) {System.out.println("收到消息: " + message);JSONObject json = JSON.parseObject(message);String type = json.getString("type");String content = json.getString("content");String target = json.getString("target");if ("private".equals(type)) {// 私聊逻辑ChannelContext targetContext = Tio.getChannelContextByToken(channelContext.getGroupContext(), target);if (targetContext != null) {Tio.send(targetContext, content.getBytes(CHARSET));}} else if ("group".equals(type)) {// 群聊逻辑Tio.sendToGroup(channelContext, "default_group", content.getBytes(CHARSET));} else if ("group_custom".equals(type)) {// 组聊逻辑(自定义群组)String groupId = json.getString("groupId");Tio.sendToGroup(channelContext, groupId, content.getBytes(CHARSET));}return null;}@Overridepublic void onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) {String userId = Tio.getUserContext(channelContext).getToken();System.out.println("用户 " + userId + " 已断开");Tio.unbindUser(channelContext, userId);Tio.unbindGroup(channelContext, "default_group");}
}
2. 用户与群组管理
@Component
public class UserService {private static final Map<String, ChannelContext> USER_MAP = new ConcurrentHashMap<>();public void bindUser(ChannelContext channelContext, String userId) {USER_MAP.put(userId, channelContext);}public void unbindUser(String userId) {ChannelContext context = USER_MAP.remove(userId);if (context != null) {Tio.close(context);}}public ChannelContext getUserContext(String userId) {return USER_MAP.get(userId);}
}
3. 组聊扩展(高级功能)
@Component
public class GroupService {private static final Map<String, Set<ChannelContext>> GROUP_MAP = new ConcurrentHashMap<>();public void joinGroup(ChannelContext context, String groupId) {GROUP_MAP.computeIfAbsent(groupId, k -> ConcurrentHashMap.newKeySet()).add(context);}public void leaveGroup(ChannelContext context, String groupId) {GROUP_MAP.getOrDefault(groupId, Collections.emptySet()).remove(context);}public void sendToGroup(String groupId, byte[] message) {GROUP_MAP.getOrDefault(groupId, Collections.emptySet()).forEach(ctx -> {try {ctx.writeAndFlush(new String(message, CHARSET));} catch (Exception e) {e.printStackTrace();}});}
}
四、测试与验证
1. 启动服务
运行 TioChatApplication,控制台输出:
TioWebSocketServer 启动成功,监听端口:8081
2. 客户端连接
使用 WebSocket 客户端连接 ws://localhost:8081,发送测试消息:
{"type": "private","target": "user123","content": "Hello Tio!"
}
3. 验证功能
- 私聊:指定
type为private,target为目标用户 ID - 群聊:发送消息时指定
type为group - 组聊:发送消息时指定
type为group_custom并携带groupId字段
Tio可以更好的拓展websocket,更方便的实现私聊,组聊和群聊的功能,其内部封装好了许多方法,详细可以查看官方文档
相关文章:
Tio-Boot 集成 Spring Boot 实现即时通讯功能全解析
Tio-Boot 集成 Spring Boot 实现即时通讯功能全解析(详细版) 一、Tio-Boot 简介 Tio-Boot 是基于 Tio 框架的 Spring Boot Starter 扩展,提供高性能、低延迟的网络通信能力,支持 TCP/UDP 协议及 WebSocket 协议,适用…...
从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(一)
项目包含5个模块 1.首页 (聊天主页) 2.注册 3.登录 4.个人资料 5.设置主题 一、配置开发环境 建立项目文件夹 mkdir chat-project cd chat-project mkdir server && mkdir webcd server npm init cd web npm create vitelatest 创建前端项目时我们选择javascrip…...
ant design 疑惑记录 Dropdown.Button
onMenuClick是点击展开的 子项的点击事件 Actions的点击事件是什么? 解答: 也是个按钮Button,也有自己的onClick事件 const onMenuClick (e) > {console.log(click, e); }; const otherClick (e) > {console.log(其他操作主按钮…...
Perplexity AI:通过OpenAI与DeepSeek彻底革新搜索和商业策略
在不断发展的AI领域,Perplexity AI已经成为一个独特的力量,正在重塑我们搜索信息的方式。 通过结合前沿的AI工具,Perplexity提供了更智能、更像人类的搜索体验。那么,这个平台与竞争对手有何不同呢? 让我们一起探索Perplexity的商业策略、它如何通过变现服务以及如何利用…...
什么是Firehose?它的作用是什么?
目录 1. Firehose 的作用 2. Firehose 文件(prog_firehose.mbn) 如何获取 Firehose 文件? 3. Firehose 模式(EDL Mode) 如何进入 EDL 模式? 4. Firehose 命令(低级操作) 5. F…...
rkipc main.c 中 rk_param_init函数分析
rk_param_init函数 这个函数是用来读取配置文件进行参数配置 这个函数在 luckfox-pico/project/app/rk_smart_door/smart_door/common/uvc/param/param.c 中 这个函数在main函数中被调用 //通过-c 配置文件路径 把配置文件传进来 case c:rkipc_ini_path_ optarg;//调用&am…...
SAP on Microsoft Azure Architecture and Administration (Ravi Kashyap)
SAP on Microsoft Azure Architecture and Administration (Ravi Kashyap)...
Missing required prop: “maxlength“
背景: 封装一个使用功能相同使用频率较高的input公共组件作为子组件,大多数长度要求为200,且实时显示统计子数,部分input有输入提示。 代码实现如下: <template><el-input v-model"inputValue" t…...
在windows下安装windows+Ubuntu16.04双系统(下)
这篇文章的内容主要来源于这篇文章,为正式安装windowsUbuntu16.04双系统部分。在正式安装前,若还没有进行前期准备工作(1.分区2.制作启动u盘),见《在windows下安装windowsUbuntu16.04双系统(上)》 二、正式安装Ubuntu …...
数据库驱动免费下载(Oracle、Mysql、达梦、Postgresql)
数据库驱动找起来好麻烦,我整理到了一起,需要的朋友免费下载:驱动下载 目前收录了Oracle、Mysql、达梦、Postgresql的数据库驱动的多个版本,后续可能会分享更多。...
业务流程相关的权威认证和培训有哪些
业务流程的认证和培训种类繁多,旨在帮助专业人士掌握业务流程管理 (BPM) 的知识和技能,从而提升个人职业发展和组织运营效率。下面分别介绍: 一、 业务流程认证和培训的种类 业务流程的认证和培训可以大致分为以下几类,涵盖了不…...
java(spring boot)实现向deepseek/GPT等模型的api发送请求/多轮对话(附源码)
我们再启动应用并获取api密钥后就可以对它发送请求了,但是官方文档对于如何进行多轮对话以及怎么自定义参数并没有说的很清楚,给的模板也没有java的,因此我们需要自己实现。 import org.json.JSONArray; import org.json.JSONObject;import j…...
vivado修改下载器下载速率
Error Launching Program X Error while launching program: fpga configuration failed. DONE PIN is not HIGH 原因是下载器速度太快了。先从任务管理器中关闭hw_server.exe试一下,要是不行就按下面三种方法解决。 第一种方法可以不用修改下载速度,直接先从vivado中将bit流…...
巧妙实现右键菜单功能,提升用户操作体验
在动态交互式图库中,右键菜单是一项能够显著提升用户操作便捷性的功能。它的设计既要响应用户点击位置,又需确保菜单功能与数据操作紧密结合,比如删除图片操作。以下将通过一段实际代码实现,展示从思路到实现的详细过程。 实现右键…...
【Altium Designer】BGA扇出
目录 一、前期规则设置 1.调整Clearance规则 2.定义线宽与过孔参数 3.配置Fanout规则 二、自动扇出操作 1.选择目标器件 2.设置扇出参数 3.执行扇出 三、手动优化与验证 1.检查未成功扇出的引脚 2.调整过孔布局 3.验证平面完整性 四、高级技巧 1.分区域扇出 2.差分对优先…...
无前端经验如何快速搭建游戏站:使用 windsurf 从零到上线的详细指南
页面初稿设计 寻找参考网站:浏览互联网,寻找一个或多个你认为设计出色的网站,将你感兴趣的页面部分进行截图保存,这些截图将成为你设计游戏站页面初稿的重要参考。利用 v0.dev 进行页面设计:打开 v0.dev 网站…...
mysql之事务深度解析与实战应用:保障数据一致性的基石
文章目录 MySQL 事务深度解析与实战应用:保障数据一致性的基石一、事务核心概念与原理1.1 事务的本质与意义1.2 事务的 ACID 特性1.2.1 原子性 (Atomicity)1.2.2 一致性 (Consistency)1.2.3 隔离性 (Isolation)1.2.4 持久性 (Durability) 1.3 事务隔离级别与并发问题…...
CASS11快捷键设置
快捷键增加如下: tr----trim bo---(-boundary) ro---rotate ed----explode of---offset qs---qselect dp---ptype re---regen rec---rectang br---break dis---distuser do---draworder...
Python进行简单医学影像分析的示例
以下是一个使用Python进行简单医学影像分析的示例,这里我们以常见的DICOM格式医学影像为例,使用pydicom库读取DICOM文件,使用matplotlib进行影像显示,使用scikit - image进行简单的影像处理。 需求复现讲解 1. 安装必要的库 在…...
anaconda安装报错
一 anaconda报错 Cannot open 本地 Failed to start [powershell.exe, -ExecutionPolicy, RemoteSigned, -NoExit, -Command, & D:\anaconda3\condabin\conda.bat shell.powershell hook | Out-String | Invoke-Expression ; try { conda activate D:/anaconda3/envs/1-man…...
git从本地其他设备上fetch分支
在 Git 中,如果你想从本地其他设备上获取分支,可以通过以下几种方式实现。不过,需要注意的是,Git 本身是分布式版本控制系统,通常我们是从远程仓库(如 GitHub、GitLab 等)拉取分支,而…...
HTTP 常见状态码技术解析(应用层)
引言 HTTP 状态码是服务器对客户端请求的标准化响应标识,属于应用层协议的核心机制。其采用三位数字编码,首位数字定义状态类别,后两位细化具体场景。 状态码不仅是服务端行为的声明,更是客户端处理响应的关键依据。本文将从协议规…...
OpenBMC:BmcWeb定义service
1.定义service //src\webserver_run.cppint run() {...std::shared_ptr<sdbusplus::asio::connection> systemBus std::make_shared<sdbusplus::asio::connection>(io);crow::connections::systemBus systemBus.get();auto server sdbusplus::asio::object_serv…...
如何使用3D高斯分布进行环境建模
使用3D高斯分布来实现建模,主要是通过高斯分布的概率特性来描述空间中每个点的几何位置和不确定性。具体来说,3D高斯分布被用来表示点云数据中的每一个点或体素(voxel)的空间分布和不确定性,而不是单纯地存储每个点的坐…...
兰州百合基因组(36.68 Gb)-文献精读113
The evolutionary tale of lilies: Giant genomes derived from transposon insertions and polyploidization 百合的进化故事:由转座子插入和多倍化导致的巨型基因组 百合(Lilium spp.),被誉为“球根花卉之王”,因其…...
如何做实用、好用的矿用电子围栏(续篇)
1 写在前面 去年写了一篇文章《如何做实用、好用的矿用电子围栏》,初步探讨了一下矿用UWB的电子围栏的实现方法,阅读量超出预期,说明电子围栏需求度比较高,企业对安全生产越来越重视。当时写这篇文章时,由于时间和理解…...
【多语言生态篇三】【DeepSeek×Go:高并发推理服务设计】
第一章:项目背景与选型考量 1.1 DeepSeek推理服务的业务挑战 日均请求量突破1.2亿次(峰值QPS达38万) 典型请求特征:50ms超时限制 | 10KB输入+2KB响应 流量特征:工作日周期性波动(早10点至晚8点负载增长300%) 1.2 Go语言脱颖而出的五大优势 (敲黑板!这里用餐馆厨房…...
【ThreeJS Basics 1-5】动画 Animations
文章目录 Three JS 中的动画window.requestAnimationFrame(fn)基本代码修改显示器刷新率的对比基础的动画尝试不同帧率导致动画速率不同解决方案一:DeltaTime解决方案2:Clock方法3: 动画库 Gsap如何选择方案? Three JS 中的动画 …...
WSL进阶使用指南
WSL2通过 Hyper-V 技术创建了一个轻量级的虚拟机(VM),在这个虚拟机之上可以运行一个真正的 Linux 内核,这给希望同时使用 Windows 和 Linux 的开发人员提供了无缝高效的体验。本文会介绍一些使用WSL的知识,帮助你更好地…...
工业机器视觉3D视觉行业分析
一、行业现状与市场前景 市场规模与增长 中国工业机器视觉市场近年来呈现高速增长态势,预计2025年市场规模将达到数百亿元,年复合增长率(CAGR)超过20%579。其中,3D视觉技术因在智能制造、人形机器人、自动驾驶等领域的广泛应用,成为核心增长点。全球3D成像与传感市场预计…...
