企业级Websocket即时通讯系统

企业级即时通讯系统实现总结

项目概述

基于 Vue 3 (JavaScript) + Spring Boot 构建的实时聊天系统,采用 WebSocket (STOMP) 协议实现消息推送。

功能特性

  • 公共频道:所有在线用户可见的广播消息
  • 私人聊天:一对一加密消息通信
  • 在线状态:实时显示用户在线/离线状态
  • 消息提醒:页面后台时标题闪烁提示

核心依赖

前端依赖(package.json)

依赖 版本 用途
vue ^3.5.24 前端框架
element-plus ^2.11.7 UI组件库
pinia ^3.0.4 状态管理
sockjs-client ^1.6.1 WebSocket封装
stompjs 2.3.3 STOMP协议客户端

后端依赖(pom.xml)

依赖 版本 用途
spring-boot-starter-parent 2.3.10.RELEASE Spring Boot父工程
spring-boot-starter-websocket - WebSocket支持
hutool-all 5.8.41 工具库
mybatis-plus-boot-starter 3.5.6 ORM框架
sa-token-spring-boot-starter 1.37.0 权限认证

核心技术实现

1. 前端实现

消息存储结构

javascript 复制代码
const publicMessages = ref([]);    // 公共消息列表
const privateMessages = ref({});   // 私人消息(按用户ID存储)

STOMP 连接

javascript 复制代码
const socket = new SockJS('/stomp');
const stompClient = Stomp.over(socket);
stompClient.connect({'token': token}, (frame) => {
    console.log('STOMP 连接成功');
});

频道订阅

  • 公共频道:/topic/public(广播模式)
  • 私人频道:/user/{userId}/queue/private(点对点)

2. 后端实现

WebSocket 配置

java 复制代码
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue", "/user");
        config.setApplicationDestinationPrefixes("/app");
    }

	@Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/stomp")// 添加 STOMP 端点
                .setHandshakeHandler(new WebSocketHandshakeHandler())// 设置握手处理程序
                .setAllowedOrigins("*")// 允许所有来源
                .withSockJS();// 开启 SockJS 支持
    }
}

自定义WebSocket握手处理类

用于处理WebSocket连接的握手请求,将用户ID绑定到WebSocket会话中

java 复制代码
@Component
@Slf4j
public class WebSocketHandshakeHandler extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(ServerHttpRequest request,
                                      WebSocketHandler wsHandler,
                                      Map<String, Object> attributes) {
        String userId = StpUtil.getLoginIdAsString();
        return new StompPrincipal(userId);
    }
}

ws用户信息封装

java 复制代码
/**
 * ws用户信息封装
 *
 * @author Chen
 * @since 2026-5-9 11:05
 */
public class StompPrincipal implements Principal {
    // 用户ID
    private final String name;


    public StompPrincipal(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }
}

消息处理

@MessageMapping("/chat/public")类型GetMapping,websocket的请求映射

java 复制代码
//前端调用
const destination = currentChannel.value === 'public'
        ? '/app/chat/public'
        : `/app/chat/private/${selectedUser.value.id}`;
    client.send(destination, {}, JSON.stringify({
          content: newMessage.CONTENT,
          fromUserId: userInfoStore.userId,
          toUserId: selectedUser.value?.id,
          msgType: 'text',
          channelType: currentChannel.value
        }
    ));

@SendTo("/topic/public")注解是将返回结果自动广播到主题:/topic/public;也可以手动广播

java 复制代码
//手动发送消息到指定用户队列
messagingTemplate.convertAndSendToUser(toUserId, "/queue/private", response);
java 复制代码
@MessageMapping("/chat/public")
@SendTo("/topic/public")
public ChatResDTO sendPublicMessage(ChatMessageDTO message) {
    return chatService.processPublicMessage(message);
}

@MessageMapping("/chat/private/{toUserId}")
public void sendPrivateMessage(ChatMessageDTO message) {
    chatService.processPrivateMessage(message, message.getToUserId());
}

消息持久化

  • 公共消息:GROUP_ID = 'public'
  • 私人消息:GROUP_ID = 'private',记录双方用户ID

技术架构

复制代码
┌─────────────────────────────────────────────────┐
│  前端 (Vue 3)                                  │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │ 侧边栏  │  │ 聊天面板 │  │ 输入框  │        │
│  └────┬────┘  └────┬────┘  └────┬────┘        │
└───────┼────────────┼────────────┼─────────────┘
        │ WebSocket  │            │
        ▼            ▼            ▼
┌─────────────────────────────────────────────────┐
│  后端 (Spring Boot)                            │
│  ChatController → ChatService → STOMP Broker   │
└───────────────────────────────┬───────────────┘
                               │ JDBC
                               ▼
┌─────────────────────────────────────────────────┐
│  数据库 (MySQL)                                │
│            CHAT_MESSAGE 表                     │
└─────────────────────────────────────────────────┘

技术栈

分类 技术
前端 Vue 3、Pinia、Element Plus
通信 SockJS、STOMP
后端 Spring Boot
数据库 MySQL、Hutool DB

总结

本系统实现了企业级即时通讯的核心功能:

  1. 实时通信:基于 STOMP 协议的毫秒级消息推送
  2. 双频道模式:公共广播 + 私人聊天
  3. 在线状态:实时同步在线用户列表
  4. 消息持久化:所有消息记录到数据库
  5. 用户体验:未读计数、后台提醒等功能

代码结构清晰,易于扩展文件传输、表情等高级功能。

相关推荐
格林黄1 天前
WebSocket vs WebRTC 音频处理对比
websocket·音视频·webrtc
格林黄1 天前
语音电子病历python_websocket实现
开发语言·python·websocket
AIFQuant2 天前
JavaScript 前端集成贵金属 K 线图:10 分钟快速实现
开发语言·前端·javascript·websocket·金融·期货api
不是山谷.:.2 天前
websocket的封装
开发语言·前端·网络·笔记·websocket·网络协议
金融大 k2 天前
Python 全球指数监控面板:TickDB + REST + WebSocket 完整方案
python·websocket
sichuanwww2 天前
WebSocket
websocket
yezipi耶不耶3 天前
讲讲 RTMate (WebSocket as A Service)中的消息的发布订阅机制
websocket·网络协议·rust
哈撒Ki3 天前
快速入门WebSocket
前端·websocket
金融大 k4 天前
多市场行情时间戳对齐:UTC 存储的夏令时陷阱与数据库设计方案
python·websocket·行情数据