首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot整合WebSocket打造在线聊天室实战!!!

SpringBoot整合WebSocket打造在线聊天室实战!!!

作者头像
用户5224393
发布于 2019-08-13 08:00:14
发布于 2019-08-13 08:00:14
2.6K00
代码可运行
举报
文章被收录于专栏:Java研发军团Java研发军团
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
作者:yizhiwazi 原文:https://www.jianshu.com/p/55cfc9fcb69e

引言

1、WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

2、浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

3、当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

得益于W3C国际标准的实现,我们在浏览器JS就能直接创建WebSocket对象,再通过简单的回调函数就能完成WebSocket客户端的编写,非常简单!接下来让我们一探究竟。

一、打造 WebSocket 聊天客户端

1、获取WebSocket客户端对象。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var webSocket = new WebSocket(url);
2、获取WebSocket回调函数。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
webSocket.onmessage = function (event) {
 console.log('WebSocket收到消息:' + event.data);
}
3、发送消息给服务端

例如:webSokcet.send(jsonStr) 结合实际场景 本案例采用JSON字符串进行消息通信。

具体实现:

下面是本案例在线聊天的客户端实现的JS代码,附带详细注释。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script>

    /**
     * WebSocket客户端
     *
     * 使用说明:
     * 1、WebSocket客户端通过回调函数来接收服务端消息。例如:webSocket.onmessage
     * 2、WebSocket客户端通过send方法来发送消息给服务端。例如:webSocket.send();
     */
    function getWebSocket() {
        /**
         * WebSocket客户端 PS:URL开头表示WebSocket协议 中间是域名端口 结尾是服务端映射地址
         */
        var webSocket = new WebSocket('ws://localhost:8080/chat');
        /**
         * 当服务端打开连接
         */
        webSocket.onopen = function (event) {
            console.log('WebSocket打开连接');
        };

        /**
         * 当服务端发来消息:1.广播消息 2.更新在线人数
         */
        webSocket.onmessage = function (event) {
            console.log('WebSocket收到消息:%c' + event.data, 'color:green');
            //获取服务端消息
            var message = JSON.parse(event.data) || {};
            var $messageContainer = $('.message-container');
            //喉咙发炎
            if (message.type === 'SPEAK') {
                $messageContainer.append(
                    '<div class="mdui-card" style="margin: 10px 0;">' +
                    '<div class="mdui-card-primary">' +
                    '<div class="mdui-card-content message-content">' + message.username + ":" + message.msg + '</div>' +
                    '</div></div>');
            }
            $('.chat-num').text(message.onlineCount);
            //防止刷屏
            var $cards = $messageContainer.children('.mdui-card:visible').toArray();
            if ($cards.length > 5) {
                $cards.forEach(function (item, index) {
                    index < $cards.length - 5 && $(item).slideUp('fast');
                });
            }
        };

        /**
         * 关闭连接
         */
        webSocket.onclose = function (event) {
            console.log('WebSocket关闭连接');
        };

        /**
         * 通信失败
         */
        webSocket.onerror = function (event) {
            console.log('WebSocket发生异常');

        };
        return webSocket;
    }

    var webSocket = getWebSocket();
    /**
     * 通过WebSocket对象发送消息给服务端
     */
    function sendMsgToServer() {
        var $message = $('#msg');
        if ($message.val()) {
            webSocket.send(JSON.stringify({username: $('#username').text(), msg: $message.val()}));
            $message.val(null);
        }
    }
    /**
     * 清屏
     */
    function clearMsg(){
      $(".message-container").empty();
    }

    /**
     * 使用ENTER发送消息
     */
    document.onkeydown = function (event) {
        var e = event || window.event || arguments.callee.caller.arguments[0];
        e.keyCode === 13 && sendMsgToServer();
    };
</script>

二、打造 WebSocket 聊天服务端

得益于SpringBoot提供的自动配置,我们只需要通过简单注解@ServerEndpoint就就能创建WebSocket服务端,再通过简单的回调函数就能完成WebSocket服务端的编写,比起客户端的使用同样非常简单!

首先在POM文件引入spring-boot-starter-websocket 、thymeleaf 、FastJson等依赖。

1、开启WebSocket服务端的自动注册。

这里需要特别提醒:ServerEndpointExporter 是由Spring官方提供的标准实现,用于扫描ServerEndpointConfig配置类和@ServerEndpoint注解实例。

使用规则也很简单:

1.如果使用默认的嵌入式容器 比如Tomcat 则必须手工在上下文提供ServerEndpointExporter。

2. 如果使用外部容器部署war包,则不要提供提供ServerEndpointExporter,因为此时SpringBoot默认将扫描服务端的行为交给外部容器处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
2、创建WebSocket服务端。

核心思路:

① 通过注解@ServerEndpoint来声明实例化WebSocket服务端。

② 通过注解@OnOpen、@OnMessage、@OnClose、@OnError 来声明回调函数。

③ 通过ConcurrentHashMap保存全部在线会话对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
@ServerEndpoint("/chat")//标记此类为服务端
public class WebSocketChatServer {
    /**
     * 全部在线会话  PS: 基于场景考虑 这里使用线程安全的Map存储会话对象。
     */
    private static Map<String, Session> onlineSessions = new ConcurrentHashMap<>();
    /**
     * 当客户端打开连接:1.添加会话对象 2.更新在线人数
     */
    @OnOpen
    public void onOpen(Session session) {
        onlineSessions.put(session.getId(), session);
        sendMessageToAll(Message.jsonStr(Message.ENTER, "", "", onlineSessions.size()));
    }
    /**
     * 当客户端发送消息:1.获取它的用户名和消息 2.发送消息给所有人
     * <p>
     * PS: 这里约定传递的消息为JSON字符串 方便传递更多参数!
     */
    @OnMessage
    public void onMessage(Session session, String jsonStr) {
        Message message = JSON.parseObject(jsonStr, Message.class);
        sendMessageToAll(Message.jsonStr(Message.SPEAK, message.getUsername(), message.getMsg(), onlineSessions.size()));
    }

    /**
     * 当关闭连接:1.移除会话对象 2.更新在线人数
     */
    @OnClose
    public void onClose(Session session) {
        onlineSessions.remove(session.getId());
        sendMessageToAll(Message.jsonStr(Message.QUIT, "", "下线了!", onlineSessions.size()));
    }
    /**
     * 当通信发生异常:打印错误日志
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }
    /**
     * 公共方法:发送信息给所有人
     */
    private static void sendMessageToAll(String msg) {
        onlineSessions.forEach((id, session) -> {
            try {
                session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

}

④ 通过会话对象 javax.websocket.Session 来发消息给客户端。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * WebSocket 聊天消息类
 */
@AllArgsConstructor
@Data
public class Message {

    public static final String ENTER = "ENTER";
    public static final String SPEAK = "SPEAK";
    public static final String QUIT = "QUIT";
    private String type;//消息类型
    private String username; //发送人
    private String msg; //发送消息
    private int onlineCount; //在线用户数
    public static String jsonStr(String type, String username, String msg, int onlineTotal) {
        return JSON.toJSONString(new Message(type, username, msg, onlineTotal));
    }![ws-gif.gif](https://upload-images.jianshu.io/upload_images/8069210-c260e9ed6c4defde.gif?imageMogr2/auto-orient/strip)
}

三、WebSocket在线聊天案例的视频演示

视频演示

上面一顿操作猛如虎,实际到底是啥样子呢,接下来由哈士奇童鞋为我们演示最终版的在线聊天案例:

全文总结

1、使用WebSocket用于实时双向通讯的场景,常见的如聊天室、跨系统消息推送等。

2、创建WebSocket客户端使用JS内置对象+回调函数+send方法发送消息。

3、创建WebSocket服务端使用注解声明实例+使用注解声明回调方法+使用Session发送消息。

以上源码下载公众号输入:springboot聊天室

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java研发军团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
yarn install命令运行报错:无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 10.x
王小婷
2021/11/24
16.1K0
yarn install命令运行报错:无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
报错:Reset-AppxPackage : 无法将“Reset-AppxPackage”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如 果包括路径,请
Reset-AppxPackage : 无法将“Reset-AppxPackage”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如 果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 51 + Get-AppxPackage Microsoft.SecHealthUI -AllUsers | Reset-AppxPackage + ~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Reset-AppxPackage:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
默 语
2025/05/21
2050
报错:Reset-AppxPackage : 无法将“Reset-AppxPackage”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如 果包括路径,请
如何解决:“无法将 ‘AI’ 项识别为 cmdlet、函数、脚本文件或可运行程序的名称”问题
大家好,我是 猫头虎 🐯! 今天和大家分享一个开发中经常遇到的问题,那就是在终端或 PowerShell 中执行命令时,出现以下错误提示:
猫头虎
2024/12/25
1.8K0
vue : 无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。
vue : 无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。
tongyao
2022/06/09
3.7K0
vue : 无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。
【错误记录】在 Android Studio 的 Terminal 终端执行 gradlew 报错 ( 无法将“gradlew”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称 )
在 Android Studio 的 Terminal 终端执行 gradlew 报错 , 报错信息如下 :
韩曙亮
2023/03/30
5K0
【错误记录】在 Android Studio 的 Terminal 终端执行 gradlew 报错 ( 无法将“gradlew”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称 )
cnpm : 无法将“cnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。所在位置 行:1 字符: 1
使用vscode终端powershell控制台查看cnpm版本或者运行cnpm的相关命令时提示如标题错误(cmd控制台提示:'cnpm' 不是内部或外部命令,也不是可运行的程序或批处理文件。)
GoodTime
2024/03/05
6.2K0
cnpm : 无法将“cnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。所在位置 行:1 字符: 1
php : 无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
php : 无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
OwenZhang
2021/12/08
4.7K0
php : 无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
2.Golang 热加载开发
工具 1(推荐):https://github.com/gravityblast/fresh
Devops海洋的渔夫
2023/11/20
4960
2.Golang 热加载开发
win10/win11需要使用新应用以打开此Windowsdefender链接
管理员权限打开PowerShell,依次执行如下3个命令即可,中途出现部署失败的红色提示可以无视,整个过程几分钟
默 语
2024/12/31
8300
win10/win11需要使用新应用以打开此Windowsdefender链接
从零开始学MYSQL - MYSQL安装
这个专栏也可以认为是学习笔记,由于之前的专栏学习的是网络上的培训机构教程,学习完成之后发现虽然讲到一些有一些深入的东西,但是讲的都不是特别深,所以从这一节开始将会从零开始来全盘了解MYSQL,这里找了一本书《从根上理解Mysql》,个人也十分推荐读者去看看这边书,不仅有新特性对接讲解,也有很多的干货,同时讲的也十分好,作为支持个人后面也买了一本实体书(虽然基本都是拿pdf看的)。
阿东
2021/11/02
6130
PowerShell5.X与WMI的集成 专题系列分享 第一部分
众所周知,在windows10以及Windows Server2016的平台当中,PowerShell5.x已经能够去获取到系 统当中大部分的信息,但有时候仍有一些信息需要借助于调用WMI的类来完成。通过本文,你可以 了解到WMI的基本架构和组件,包括WMI的数据库,WMI的provider,以及在PowerShell调用WMI的 时候提供的module和相关的命令。接下来我们就能通过powershell的命令去完成WMI的查询操作, 去获取到系统当中WMI的实例。然后我们还可通过实例的属性查看到系统当中不同的信息,同时的 话去调用实例当中为我们提供的不同的方法,去修改系统信息的配置。
Ms08067安全实验室
2020/12/31
9450
解决:无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
如果我们已经安装了PHP或者其他集成环境,但是在命令行执行php命令时还是报这个错误
唯一Chat
2023/02/02
3.3K0
解决:无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
python安装步骤(pycharm运行python)
你可能接下来会看到很多图片,因为我截图十分详细了每一步,保证每一个人看懂,所以图很多。中途也遇到了小问题,不要担心,我都有解决。
全栈程序员站长
2022/07/25
1.1K0
python安装步骤(pycharm运行python)
【Python】已解决:(MongoDB安装报错)‘mongo’ 不是内部或外部命令,也不是可运行的程序
在安装和配置MongoDB时,有时会遇到“‘mongo’ 不是内部或外部命令,也不是可运行的程序”的错误提示。这个错误通常发生在Windows操作系统中,当用户尝试在命令行界面(CMD)或PowerShell中运行mongo命令以启动MongoDB shell时。
屿小夏
2025/05/23
3030
一文弄懂Jupyter的配置与使用(呕心沥血版)
安装 Python。从 Python 官方网站[1]下载最新版本的 Python。
MinChess
2023/05/01
22.7K0
一文弄懂Jupyter的配置与使用(呕心沥血版)
JavaSE 编写第一个程序
介绍 JavaSE 基础的基本语法知识,不会包含特别难以理解或更深层次的内容,通俗易懂。本人是实战派,看着大幅篇章晦涩的理论,但是没有多少实践证明的书籍就头疼;同时如果知识东一点、西一点,跳跃性太大,不成体系,也比较麻烦。
全栈程序员站长
2022/09/14
6.7K0
JavaSE 编写第一个程序
硬件资料和软件资料_电脑硬件检测工具哪个好
2. BIOS报警声意义 3. BIOS自检与开机故障相关问题 5. 计算机几个常见指标的意义 6. 显卡GPU参数 7. 显示卡常见故障全面解决 8. 集成声卡常见故障及解决 9. 显示器经典故障以及处理办法 10. AMI主板代码大全(BIOS-ID)
全栈程序员站长
2022/11/01
4.9K0
Python100Days
这可能是我目前发现最好最好的Python教程了,故整理至我的博客。 原项目GitHub地址https://github.com/jackfrued/Python-100-Days
一点儿也不潇洒
2018/08/07
10K0
[PHP] 2018年终总结
========================================================================== 2018年12月29日 记录:
唯一Chat
2019/09/10
2.8K0
推荐阅读
yarn install命令运行报错:无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
16.1K0
报错:Reset-AppxPackage : 无法将“Reset-AppxPackage”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如 果包括路径,请
2050
如何解决:“无法将 ‘AI’ 项识别为 cmdlet、函数、脚本文件或可运行程序的名称”问题
1.8K0
vue : 无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。
3.7K0
【错误记录】在 Android Studio 的 Terminal 终端执行 gradlew 报错 ( 无法将“gradlew”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称 )
5K0
cnpm : 无法将“cnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。所在位置 行:1 字符: 1
6.2K0
php : 无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
4.7K0
2.Golang 热加载开发
4960
win10/win11需要使用新应用以打开此Windowsdefender链接
8300
从零开始学MYSQL - MYSQL安装
6130
PowerShell5.X与WMI的集成 专题系列分享 第一部分
9450
解决:无法将“php”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
3.3K0
python安装步骤(pycharm运行python)
1.1K0
【Python】已解决:(MongoDB安装报错)‘mongo’ 不是内部或外部命令,也不是可运行的程序
3030
一文弄懂Jupyter的配置与使用(呕心沥血版)
22.7K0
JavaSE 编写第一个程序
6.7K0
硬件资料和软件资料_电脑硬件检测工具哪个好
4.9K0
Python100Days
10K0
[PHP] 2018年终总结
2.8K0
相关推荐
yarn install命令运行报错:无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档