百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

SpringBoot 使用WebSocket打造在线聊天室(基于注解)

bigegpt 2024-10-19 02:52 7 浏览

原文地址:https://dwz.cn/87Mq3Br1

作者:yizhiwazi

推荐WebSocket的三大理由:

  • 1、采用全双工通信,摆脱传统HTTP轮询的窘境。
  • 2、采用W3C国际标准,完美支持HTML5。
  • 3、简单高效,容易上手。

学习目标

快速学会通过WebSocket编写简单聊天功能。

温馨提示:

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

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

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

使用教程

一、打造 WebSocket 聊天客户端

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

使用说明:

使用步骤:1、获取WebSocket客户端对象。

例如: var webSocket = new WebSocket(url);

使用步骤:2、获取WebSocket回调函数。

例如:webSocket.onmessage = function (event) {console.log('WebSocket收到消息:' + event.data);

使用步骤:3、发送消息给服务端

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

具体实现:

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

<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默认将扫描服务端的行为交给外部容器处理。】

@Configuration
public class WebSocketConfig {
 @Bean
 public ServerEndpointExporter serverEndpointExporter() {
 return new ServerEndpointExporter();
 }
}

使用步骤:2、创建WebSocket服务端。

核心思路:

  • ① 通过注解@ServerEndpoint来声明实例化WebSocket服务端。
  • ② 通过注解@OnOpen、@OnMessage、@OnClose、@OnError 来声明回调函数。
  • ③ 通过ConcurrentHashMap保存全部在线会话对象。
@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 来发消息给客户端。
/**
 * WebSocket 聊天消息类
 */
package com.hehe.chat;
import com.alibaba.fastjson.JSON;
/**
 * WebSocket 聊天消息类
 */
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));
 }
 public Message(String type, String username, String msg, int onlineCount) {
 this.type = type;
 this.username = username;
 this.msg = msg;
 this.onlineCount = onlineCount;
 }
 //这里省略get/set方法 请自行补充
}

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

1、源码下载

至此,我们完成了客户端和服务端的编码,由于篇幅有限,本教程的页面代码并未完整贴上,想要完整的体验效果请在Github下载源码。

2、视频演示

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

四、全文总结

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

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

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

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...