V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
TyCoding
V2EX  ›  Java

基于 SpringBoot + WebSocket 的在线聊天系统,实现单窗口消息推送、群消息推送、上线提醒等

  •  
  •   TyCoding ·
    TyCoding · 2019-06-16 16:49:16 +08:00 · 4044 次点击
    这是一个创建于 2018 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基于 WebSocket 的在线聊天系统

    Build Status Downloads Coverage Status Coverage Status

    Github 源码:boot-chat 欢迎 star,fork 支持

    由于本人也在学习,技术有限。如果项目有问题,可以反馈、如果你有更好的解决方案请尽快联系我,谢谢~

    线上地址

    Chat

    注意!注意!注意!

    当前版本中,使用 HTTPSession 储存的 WebSocket 会话消息(包括登录用户信息),因此就不可避免的会遇到 Session 不能被共享导致的数据丢失。

    因此,在我部署的线上地址上可能出现数据丢失。如果是测试学习,请使用同一个浏览器换用不同用户登录,就不会产生上述问题了。

    SO,后续我会使用 Redis 储存 WebSocket 的会话消息(当前版本的优点就是开箱即用,只需要 JDK 环境即可运行项目打包 jar )。

    正在开发中,欢迎 star、fork 关注哦~~

    介绍

    基于 SpringBoot-2.1.5、SpringBoot-Starter-Websocket 构建,前端使用 Vue.js 、ElementUI 框架。

    实现了:

    • HttpSession 消息储存
    • 单窗口消息推送
    • 群发消息推送
    • 上线提醒
    • 实时刷新用户列表、消息列表

    虫子 无聊之余,可以来耍一耍!

    特点

    因为 WebSocket 的特性,虽然能实时接收到消息,但每次刷新浏览器,之前发送过的消息都会丢失,因此这里实现了消息储存功能。

    利用 HttpSession,将每次会话,用户推送的消息都储存到 HttpSession 中。前端利用 Vue 的 created() 钩子函数,每次刷新页面时都先请求获取 HTTPSession 中已储存的消息列表。

    因为涉及到单窗口推送消息、群发消息的限定:

    这里规定了 HttpSession 中会话消息的前缀标识,以此来区分不同的消息,具体参看:CommonConstant.java

    • CHAT_COMMON_PREFIX = "CHAT_COMMON_": 群发消息 Session Key 前缀标识

    • CHAT_FROM_PREFIX = "CHAT_FROM_": 推送方 Session Key 前缀标识

    • CHAT_TO_PREFIX = "_TO_": 接收方 Session Key 前缀标识

    文档

    看了上图你大概知道了 HTTPSession 中储存的消息格式,下面 Debug 看下具体的消息内容,供大家学习参考:

    群发消息

    这里使用一个固定的官方群组窗口,展示每个用户群发的消息。

    消息特点:

    • 多个用户发送
    • 每个用户发送多条消息

    So,HTTPSession 中储存的群发消息应该有以下约定:

    • Session Key 中包含用户的 ID 标识
    • Session Value 应该储存着该 Key 用户的所有消息(可使用 List 集合储存)

    栗子:

    单窗口消息推送

    对于给指定窗口消息,需要考虑以下几点:

    • 推送方是谁?接收方是谁?
    • 推送方可能会推送多条消息,并且推送方可能会给多个窗口推送消息。
    • 如何区分是公共消息还是指定窗口消息?

    So,HTTPSession 中储存的但窗口消息应该有以下约定:

    • Session Key 应该包含推送方 ID 标识和接收方 ID 标识,以此区分给多个窗口推送
    • Session Value 应该储存着该推送方给该接受方推送的所有消息( List 集合)

    栗子:

    运行&&部署

    # 运行
    
    $ git clone https://github.com/TyCoding/boot-chat
    -- use idea & eclipse run
    
    # 部署
    
    $ mvn clean package
    $ cd taget
    $ java -jar boot-chat-0.0.1-SNAPSHOT.jar
    

    Access http://localhost:8080 using Chrome

    关于我

    传送门

    预览

    11 条回复    2019-06-17 11:47:42 +08:00
    nicenan
        1
    nicenan  
       2019-06-16 16:55:11 +08:00 via Android
    马克马克
    zhuawadao
        2
    zhuawadao  
       2019-06-16 16:56:00 +08:00
    支持
    TyCoding
        3
    TyCoding  
    OP
       2019-06-16 17:02:57 +08:00
    @nicenan
    @zhuawadao 蟹蟹蟹蟹,可以点亮右上角 star 哦
    geekaven
        4
    geekaven  
       2019-06-16 17:06:02 +08:00
    学习了
    santana2000
        5
    santana2000  
       2019-06-16 17:06:20 +08:00
    支持支持
    qinxi
        6
    qinxi  
       2019-06-16 21:32:33 +08:00
    看了一下. 没有 redis/mq 的依赖. 应该还不支持集群部署.
    bxb100
        7
    bxb100  
       2019-06-16 21:50:22 +08:00
    乍一看以为是 IM 解决方案, 仔细一看是个玩具

    忽略以上, 支持实践
    nyfok
        8
    nyfok  
       2019-06-16 22:13:48 +08:00
    mark 不错,有移动 h5 版本的么
    sodadev
        9
    sodadev  
       2019-06-17 08:26:47 +08:00 via iPhone
    我也在写这块的功能 就是文件传输功能不好用 请问有什么需要注意的地方吗😑
    zw1one
        10
    zw1one  
       2019-06-17 10:23:25 +08:00 via Android
    star 支持
    rizon
        11
    rizon  
       2019-06-17 11:47:42 +08:00
    给楼主点赞,已 star。
    为什么我做的 在线记事本就没人给 star 呢? 这个支持协同编辑(只能 PC ),使用 event stream 做的,没用 ws。我觉得协同和聊天也有点相似之处哈。

    测试地址(如果没其他人在线可以自己多开窗口测试): http://notelive.cc/#v2ex
    github 地址: https://github.com/othorizon/notelive_webpack
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1368 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:22 · PVG 01:22 · LAX 09:22 · JFK 12:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.