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

SpringBoot+WebSocket搭建多人在线聊天环境

一、WebSocket是什么?

WebSocket是在单个TCP连接上进行全双工通信的协议,可以在服务器和客户端之间建立双向通信通道。

WebSocket 首先与服务器建立常规 HTTP 连接,然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、WebSocket的优点

1.较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于控制协议的数据包头部较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。

2.更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。

3.保持连接状态。与HTTP不同的是,WebSocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息,而HTTP请求可能需要在每个请求都携带状态信息,比如身份认证等。

4.更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。

5.可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。

6.更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

三、项目实战

1.引入依赖

<!--websocket-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

完整的pom文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.14</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>WebSocketChatDemo</artifactId><version>0.0.1-SNAPSHOT</version><name>WebSocketChatDemo</name><description>WebSocketChatDemo</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!--lombok插件依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.创建SystemWebSocketHandler类

package com.example.websocketchatdemo.websocket;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** @author qx* @date 2023/8/22* @des WebSocket处理类*/
@Slf4j
@Component
public class SystemWebSocketHandler implements WebSocketHandler {// 存储所有客户端会话private static final List<WebSocketSession> sessionList = new ArrayList<>();/*** 与服务器连接成功*/@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {log.info("客户端成功建立连接:{}", session.getId());sessionList.add(session);}/*** 接受客户端的消息*/@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {// 获取客户端的消息String msg = message.getPayload().toString();log.info("接收到客户端的消息:{}", msg);sendMsg(msg);}/*** 给所有客户端发送消息** @param msg 消息内容* @throws IOException*/private void sendMsg(String msg) throws IOException {for (WebSocketSession session : sessionList) {if (session.isOpen()) {session.sendMessage(new TextMessage(msg));}}}/*** 通讯异常*/@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {log.error("通讯出现异常");}/*** 连接关闭*/@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {log.info("连接关闭");}/*** 是否允许分段发送*/@Overridepublic boolean supportsPartialMessages() {// 一次性发送消息return false;}
}

3.创建WebSocket配置类

这个配置类主要进行跨域的配置。

package com.example.websocketchatdemo.websocket;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;/*** @author qx* @date 2023/8/22* @des WebSocket配置类*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebMvcConfigurer, WebSocketConfigurer {@Autowiredprivate SystemWebSocketHandler handler;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {// 设置WebSocket服务器地址 ws://localhost:8080/SpringBootWebSocketregistry.addHandler(handler, "/SpringBootWebSocket").setAllowedOrigins("*");}
}

4.前台页面编写

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>聊天室</title></head>
<body>
聊天消息内容:
<br/>
<textarea id="chat_content" readonly style="height: 400px;width: 600px"></textarea>
<br/>输入框:
<br/>
<div><textarea id="in_content" placeholder="请输入内容" style="height: 100px;width: 500px"></textarea>
</div>
<button type="button" id="btn_send">发送消息</button>
<br/><br/>
<label>用户:</label>
<div><input type="text" id="in_name" placeholder="请输入姓名"/>
</div>
<br/>
<button type="button" id="btn_join">进入聊天室</button>
<button type="button" id="btn_quit">离开聊天室</button>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script>$(function () {var socketUrl = "ws://localhost:8080/SpringBootWebSocket";var ws = null;$("#btn_join").click(function () {if (ws != null) {alert("用户[" + $("#in_name").val() + "]已加入连接");return;}// 判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {ws = new WebSocket(socketUrl)} else {alert("当前浏览器不支持WebSocket");}// 建立连接ws.onopen = function (event) {console.log('与服务器建立连接');ws.send("您的好友[" + $("#in_name").val() + "]上线了");}// 接收服务端返回给前端的消息ws.onmessage = function (event) {$("#chat_content").append(event.data + "\n");}// 连接关闭ws.onclose = function () {console.log("与服务器断开连接")$("#chat_content").append("用户[" + $("#in_name").val() + "]离开聊天室" + "\n");$("#in_name").val("");}});//发送消息$("#btn_send").click(function () {if (ws == null) {alert("该用户不在线");return;}var msg = $("#in_content").val();ws.send("用户[" + $("#in_name").val() + "]:" + msg);})// 离开聊天室$("#btn_quit").click(function () {ws.send("用户[" + $("#in_name").val() + "]离开聊天室!");$("#in_content").val("");ws.close();})})
</script>
</body>
</html>

5.控制器编写

主要编写一个跳转到聊天室的请求

package com.example.websocketchatdemo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;/*** @author qx* @date 2023/8/22* @des 测试*/
@Controller
@RequestMapping("/chat")
public class IndexController {/*** 跳转到聊天室*/@GetMapping("/index")public String toChat() {return "index";}
}

6.测试

我们启动项目,打开两个聊天页面。

方便设置两个用户加入聊天室

 

 

然后在一个用户中发送消息,我们可以看到两个聊天窗口的消息同步了。

 

 

当一个用户退出聊天室时,会提示用户退出聊天室。

 这个时候另一个用户发送消息只能自己看到了。

 

 如果想测试多个用户,再从新打开一个页面,进入聊天室就可以了。

相关文章:

SpringBoot+WebSocket搭建多人在线聊天环境

一、WebSocket是什么&#xff1f; WebSocket是在单个TCP连接上进行全双工通信的协议&#xff0c;可以在服务器和客户端之间建立双向通信通道。 WebSocket 首先与服务器建立常规 HTTP 连接&#xff0c;然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。 WebSocket使得…...

推荐适用于不同规模企业的会计软件:选择最适合您企业的解决方案

高效的会计软件不仅可以协助企业进行财务管理&#xff0c;做出科学的财务决策&#xff0c;还可以对企业数字化转型提供助力。不同规模的企业需要根据其特定需求选择适合的会计软件。那么有什么适合不同规模企业的会计软件推荐吗&#xff1f; 小型企业的选择 对于小型企业而言&…...

Apache Zookeeper架构和选举机制

ZooKeeper是一个开源的分布式协调服务,旨在解决分布式系统中的一致性、配置管理、领导者选举等问题。它由Apache软件基金会维护,是Hadoop生态系统的一部分,被广泛用于构建高可用、可靠和具有一致性的分布式应用程序和服务。 ZooKeeper提供了一个层次化的命名空间,类似于文…...

车联网TCU USB的配置和使用

1 usb_composition命令 # cat /sbin/usb/target # cd /sys/class/android_usb/android0 # cat functions console shows that QCOM’s default configuration Usage: usb_composition [Pid] [HSIC] [PERSISTENT] [IMMEDIATE] [FROM_ADBD] usb_composition 9025 n y y Then this…...

Linux系统USB摄像头测试程序(三)_视频预览

这是在linux上usb摄像头视频预览程序&#xff0c;此程序用到了ffmpeg、sdl2、gtk3组件&#xff0c;程序编译之前应先安装他们。 #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <zconf.h> …...

目标检测任务数据集的数据增强中,图像水平翻转和xml标注文件坐标调整

需求&#xff1a; 数据集的数据增强中&#xff0c;有时需要用到图像水平翻转的操作&#xff0c;图像水平翻转后&#xff0c;对应的xml标注文件也需要做坐标的调整。 解决方法&#xff1a; 使用pythonopencvimport xml.etree.ElementTree对图像水平翻转和xml标注…...

系统架构的演变

随着互联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的应用架构已无法应对&#xff0c;分布式服务架构以及微服务架构势在必行&#xff0c;必需一个治理系统确保架构有条不紊的演进。 单体应用架构 Web应用程序发展的早期&#xff0c;大部分web工程(包含前端…...

IDC发布《亚太决策支持型分析数据平台评估》报告,亚马逊云科技位列“领导者”类别

日前&#xff0c;领先的IT市场研究和咨询公司IDC发布《2023年亚太地区&#xff08;不含日本&#xff09;决策支持型分析数据平台供应商评估》1报告&#xff0c;亚马逊云科技位列“领导者”类别。IDC认为&#xff0c;亚马逊云科技在解决方案的协同性、敏捷性、完整性、及时性、经…...

C#之OpenFileDialog创建和管理文件选择对话框

OpenFileDialog 是用于图形用户界面&#xff08;GUI&#xff09;编程的一个类&#xff0c;它用于显示一个对话框&#xff0c;允许用户选择要打开的文件。在需要用户加载或打开文件的应用程序中&#xff08;如文本编辑器、图像查看器或文档处理器&#xff09;&#xff0c;这是一…...

Java中使用MongoTemplate 简单操作MongoDB

Autowired private MongoTemplate mongoTemplate; User&#xff1a;封装的对象 插入&#xff1a;mongoTemplate.insert(user); 根据id查询&#xff1a;mongoTemplate.findById(id, User.class); 查询所有&#xff1a;mongoTemplate.findAll(User.class); 条件查询&#…...

[Mac软件]Pixelmator Pro 3.3.12 专业图像编辑中文版

Pixelmator Pro是专为Mac设计的功能强大&#xff0c;美观且易于使用的图像编辑器。借助广泛的专业级无损图像编辑工具&#xff0c;Pixelmator Pro可使您发挥出最佳的照片效果&#xff0c;创建华丽的构图和设计&#xff0c;绘制&#xff0c;绘画&#xff0c;应用令人惊叹的效果&…...

吴恩达 GPT Prompting 课程

Prompting Guidelines 目录 Guidelines for PromptingPrompting Principles Principle 1: Write clear and specific instructions1.1: Use delimiters to clearly indicate distinct parts of the input1.2: Ask for a structured output1.3: Ask the model to check whether …...

gpt3.5写MATLAB代码剪辑视频,使之保留画面ROI区域

% 输入和输出文件名 inputVideoFile input_video.mp4; outputVideoFile output_video.mp4;% 创建 VideoReader 和 VideoWriter 对象 videoReader VideoReader(inputVideoFile); outputVideo VideoWriter(outputVideoFile, MPEG-4); outputVideo.FrameRate videoReader.Fra…...

设计模式二十一:状态模式(State Pattern)

一个对象的内部状态发生变化时&#xff0c;允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类&#xff0c;主要目的是将状态的行为从主要对象中分离出来&#xff0c;使得主要对象不必包含所有状态的逻辑&#xff0c;而是将每个状态的行为封装在独立的类…...

【校招VIP】产品思维能力之产品设计

考点介绍&#xff1a; 对于产品经理来说最重要的就是产品思维&#xff0c;而拥有一个好的产品思维需要做到以下三点&#xff1a; 1、把握关键点的能力 2、出方案&#xff0c;协调资源&#xff0c;说服团队把资源倾斜到关键点上的能力 3、评估关键点进展程度的能力 『产品思维能…...

微信小程序卡片横向滚动竖图

滚动并不是使用swiper&#xff0c;该方式使用的是scroll-view实现 Swiper局限性太多了&#xff0c;对竖图并不合适 从左往右滚动图片示例 wxml代码&#xff1a; <view class"img-x" style"margin-top: 10px;"><view style"margin: 20rpx;…...

SpringBoot项目(支付宝整合)——springboot整合支付宝沙箱支付 从极简实现到IOC改进

目录 引出git代码仓库准备工作支付宝沙箱api内网穿透 [natapp.cn](https://natapp.cn/#download) springboot整合—极简实现版1.导包配置文件2.controller层代码3.进行支付流程4.支付成功回调 依赖注入的改进1.整体结构2.pom.xml文件依赖3.配置文件4.配置类&#xff0c;依赖注入…...

【AIGC】一款离线版的AI智能换脸工具V2.0分享(支持图片、视频、直播)

随着人工智能技术的爆发&#xff0c;AI不再局限于大语言模型&#xff0c;在图片处理方面也有非常大的进步&#xff0c;其中AI换脸也是大家一直比较感兴趣的&#xff0c;但这个技术的应用一直有很大的争议。 今天给大家分享一个开源你的AI换脸工具2.0&#xff0c;只需要一张所需…...

管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容选言——或

文章目录 第五章 选言命题:相容选言-或;不相容选言-要么要么第一节 选言-相容选言-或-推结论-A或B为真,则非A→B,非B→A(否一则肯一)真题(2010-28)-选言-相容选言-或-推结论-(1)A或B为真,A为假:得B为真(否一则肯一);真题(2012-29)-选言-相容选言-或-推结论-(1)…...

Git如何操作本地分支仓库?

基本使用TortoiseGit 操作本地仓库(分支) 分支的概念 几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来&#xff0c;避免影响开发主线。多线程开发,可以同时开启多个任务的开发&#xff0c;多个任务之间互不影响。 为何要…...

WPS右键新建没有docx pptx xlsx 修复

解决wps右键没有新建文档的问题 右键没有新建PPT和Excel 1 wps自带的修复直接修复没有用 以上不管咋修复都没用 2 先编辑注册表 找到 HKEY_CLASSES_ROOT CTRLF搜文件扩展名 pptx docx xlsx 新建字符串 三种扩展名都一样操作 注册表编辑之后再次使用wps修复 注册组件&am…...

【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“

文章目录 前言&#x1f31f;一、函数重载&#x1f30f;1.1.函数重载概念&#x1f30f;1.2.C支持函数重载的原理 -- 名字修饰 &#x1f31f;二、引用&#x1f30f;2.1.引用的概念&#x1f30f;2.2.引用特性&#x1f30f;2.3.常引用&#x1f30f;2.4.使用场景&#x1f30f;2.5.传…...

【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)

【关键字】 音频编码、管道模式、createEncoder 【写在前面】 在使用API6开发HarmonyOS应用时&#xff0c;如何将pcm源文件进行编码并写入文件&#xff0c;最后生成aac文件&#xff0c;本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】 import ohos.media.codec.…...

KaiwuDB CTO 魏可伟:回归用户本位,打造“小而全”的数据库

8月16日&#xff0c;KaiwuDB 受邀亮相第十四届中国数据库技术大会 DTCC 2023。KaiwuDB CTO 魏可伟接受大会主办方的采访&#xff0c;双方共同围绕“数据库架构演进、内核引擎设计以及不同技术路线”展开深度探讨。 以下是采访的部分实录 ↓↓↓ 40 多年前&#xff0c;企业的数…...

行业追踪,2023-08-22

自动复盘 2023-08-22 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…...

浏览器安装selenium驱动,以Microsoft Edge安装驱动为例

Selenium是一个用于Web应用程序测试的自动化工具。它可以直接在浏览器中运行&#xff0c;模拟真实用户对浏览器进行操作。利用selenium&#xff0c;可以驱动浏览器执行特定的动作&#xff0c;比如&#xff1a;点击、下拉等等&#xff0c;还可以获取浏览器当前呈现的页面的源代码…...

边缘计算网关是如何提高物联网的效率的?

随着物联网的持续发展&#xff0c;物联网应用的丰富和规模的扩大&#xff0c;带来了海量的数据处理、传输和计算需求。 传统的“数据中央处理”模式越来越难以适应物联网的扩展速度&#xff0c;在这一趋势下&#xff0c;边缘计算在物联网系统的部署运营中就发挥出了显著的增效…...

AWVS安装~Windows~激活

目录 1.下载安装包 2.双击acunetix_15.1.221109177.exe进行安装 3.配置C:\Windows\System32\drivers\etc\hosts 4.复制wvsc.exe到C:\Program Files (x86)\Acunetix\15.1.221109177下 5.复制license_info.json与wa_data.dat到C:\ProgramData\Acunetix\shared\license下&…...

ATFX汇市:杰克逊霍尔年会降至,鲍威尔或再发鹰派言论

环球汇市行情摘要—— 昨日&#xff0c;美元指数下跌0.11%&#xff0c;收盘在103.33点&#xff0c; 欧元升值0.22%&#xff0c;收盘价1.0898点&#xff1b; 日元贬值0.58%&#xff0c;收盘价146.23点&#xff1b; 英镑升值0.18%&#xff0c;收盘价1.2757点&#xff1b; 瑞…...

Zipkin开源的分布式链路追踪系统

Zipkin是一款开源的分布式链路追踪系统,主要功能包括: 1. 采集跟踪数据 - Zipkin client库负责收集并上报各服务的请求信息。 2. 存储跟踪数据 - 存储层默认采用Zipkin自带的基于内存的快速存储,也支持整合MySQL、Cassandra等外部存储。 3. 查询接口 - 提供RESTful API进行跟…...

wordpress 建站 视频 百度云/摘抄一小段新闻

举例&#xff1a; 注意&#xff1a;在声明中函数的第二个参数给定了缺省值NULL&#xff0c;如果调用时候不指定具体参数&#xff0c;程序则按NULL处理&#xff0c;如果指定了具体值&#xff0c;则按照实际处理。下面是使用例子。 这样处理可以节省代码。解决有时候需要两个重载…...

苹果网站上物体阴影怎么做的/整站快速排名

列表&#xff1a;1.创建列表&#xff08;1&#xff09;直接将一个列表对象赋给变量>>> a[1,2,3,4,5] >>> a [1, 2, 3, 4, 5]>>> a_list[a,b,mpilgrim,z,example] >>> a_list [a, b, mpilgrim, z, example] >>> a_list[] #创建空…...

用凡客建站做的网站有哪些/山东大学经济研究院

近两年像LOL、吃鸡这种竞技类游戏从来都是国内游戏市场中的常青树&#xff0c;尤其是英雄联盟&#xff0c;运营多年至今热度不减反增&#xff0c;保持这种状态实在难能可贵&#xff0c;其中很大的原因是这种MOBA类游戏往往靠技术说话&#xff0c;而至于氪金多少只能彰显在外观是…...

免费的小网站/网站定制的公司

说到远程桌面演示&#xff0c;我们首先想到的不是qq就是yy,可是转念一想我们又会感觉要么是卡顿&#xff0c;要么是不够清晰&#xff0c;要么是延迟比较大&#xff0c;要么是共享桌面的屏幕看起来很小的一块需要来回拖动不够便捷直观。那么远程桌面演示最清晰最直观最流畅无延迟…...

影视网站设计/汕头网站关键词推广

wellcms伪静态设置.为了保证更强劲的性能和节省流量&#xff0c;独立安装版自动对php文件和html进行压缩&#xff0c;考虑到js或jquery每个人在写代码的时候使用注释方式的不同&#xff0c;所以html默认压缩了除js以外的全部代码。如需开启压缩模式&#xff0c;请务必卸载非wel…...

群晖 做网站/河南网站排名优化

一、上手第一个程序 1、系统要求 此处以我自己使用的版本为例&#xff0c;在后期学习过程中遇到一些问题&#xff0c;我也会试着给出解决方案 Java8Maven 3.6.3idea 2022.2.3 配置我们Maven的 setting.xml 指定了镜像源和使用的JDK版本 <mirrors><mirror><id&g…...