当前位置: 首页 > news >正文

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: 8080

tio:
  websocket:
    server:
      ip: 127.0.0.1
      heartbeat-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";

    @Override
    public 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;
    }

    @Override
    public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) {
        System.out.println("用户 " + channelContext.getToken() + " 已连接");
    }

    @Override
    public 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;
    }

    @Override
    public 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. 验证功能

  • 私聊:指定 typeprivatetarget 为目标用户 ID
  • 群聊:发送消息时指定 typegroup
  • 组聊:发送消息时指定 typegroup_custom 并携带 groupId 字段

Tio可以更好的拓展websocket,更方便的实现私聊,组聊和群聊的功能,其内部封装好了许多方法,详细可以查看官方文档

相关文章:

  • 运维脚本——9.配置漂移检测
  • 【Linux内核】进程管理(下)
  • directx12 3d开发过程中出现的报错 十三
  • 全链路优化:如何让单点登录认证接口并发性能翻倍?
  • 鸿蒙开发环境搭建-入门篇
  • 网络运维学习笔记 017 HCIA-Datacom综合实验01
  • 区块链相关方法-SWOT分析
  • 侯捷 C++ 课程学习笔记:内存管理与工具应用
  • socket()函数的概念和使用案例
  • Java 使用websocket
  • 【Linux】34.封装 UdpSocket(1)
  • 【读书笔记·VLSI电路设计方法解密】问题53:什么是逻辑综合
  • bind()函数的概念和使用案例
  • WPF实现打印机控制及打印
  • JavaScript 数组连接方法
  • java中的Entry类,map接口
  • 值传递,引用传递
  • TIP: Flex-DLD
  • 人工智能学习环境配置
  • HTTP Keep-Alive:性能优化的关键机制
  • 人民日报钟声:平等对话是解决大国间问题的正确之道
  • 游客称在网红雪山勒多曼因峰需救援被开价2.8万,康定文旅:封闭整改
  • 云南一餐馆收购长江野生鱼加工为菜品,被查处罚款
  • 代理销售保险存在误导行为,农业银行重庆市分行相关负责人被罚款0.1万元
  • 吉林市马拉松5月18日开赛,奖牌、参赛服公布
  • 海南省三亚市委原常委、秘书长黄兴武被“双开”