SocketWeb实现小小聊天室
SocketWeb实现小小聊天室
- 消息推送的常见方式
- 轮询
- 长轮询
- SSE(server-sent event):服务器发送事件
- WebSocket
- WebSocket简介
- WebSocket API
- 实现小小聊天室
- 实现流程
- 消息格式
- 客户端-->服务端
- 服务端-->客户端
消息推送的常见方式
轮询
浏览器以指定的时间间隔,向服务器发送HTTP请求,服务器将会实时地返回数据给浏览器。
例如,浏览器端可以定时每秒钟一次给后端发HTTP请求,服务端若有数据会实时返回给浏览器,浏览器通过前端展示出来。假设服务器端没有数据更新,则依然会返回一个空的数据。

轮询的弊端:
- 易造成浏览器端数据更新的延迟
- 服务器需要不停地处理浏览器发过来的请求,即使没有数据更新也需要定时发送空数据,给服务器造成较大负担
长轮询
长轮询时浏览器会发出ajax请求(异步的javascript和xml请求),服务器端接收到请求后,会阻塞请求,直到有数据更新或者超时,才会返回。HTTP/1.1采用的长链接就是这种方式。
与轮询的区别就在于:若服务器端无数据更新,轮询会返回空数据,长轮询则会阻塞住,直到超时或数据更新,减少了返回的次数,也减轻了服务器的压力。

SSE(server-sent event):服务器发送事件
SSE会在服务器和客户端之间打开一个单向通道(服务器向浏览器传输),服务器响应的不再是一次性的数据包,而是text/event-stream类型的数据流信息,当服务器有数据变更时,将数据流式地传输到客户端。
例如浏览器请求下载一个大文件时,就会以流式传输源源不断下载数据到客户端。

浏览器先发出请求,服务器响应并在二者之间打开一个单向通道,然后服务器开始向浏览器源源不断地传输流式数据,直到连接关闭。
WebSocket
WebSocket简介
WebSocket是一种基于TCP连接上进行全双工通信的协议。
(附HTTP协议工作模式:
http1.0:单工。因为是短连接,客户端发起请求之后,服务端处理完请求并收到客户端的响应后即断开连接
http1.1:半双工。默认开启长连接keep-alive,开启一个连接可发送多个请求
http2.0:全双工,允许服务端主动向客户端发送数据)

客户端先发送HTTP请求,请求中包含一个upgrade:websocket字段,即请求将HTTP协议升级为websocket协议,服务端响应头状态为101,表示同意将HTTP协议升级成websocket协议。
切换为websocket协议后,就可以实现全双工通信了。服务器可以主动发数据给客户端,二者之间也可以同时互相发送消息。
WebSocket API
客户端API
现在HTML5已经支持websocket协议。
- 创建websocket对象:
let ws = new WebSocket(URL); - websocket对象相关事件:
open 连接建立时触发:ws.open
message 客户端接收到服务器发送的数据时触发 ws.onmessage
close 连接关闭时触发 ws.onclose - websocket对象提供的方法
send()方法:通过websocket对象调用send()方法发送数据给服务端,参数即为要发送的数据
<script>let ws = new WebSocket("ws://localhost/chat");ws.open = function(){};es.onmessage = function(evt){//通过evt.data可以获取服务器发送的数据};ws.onclose = function(){};
</script>
服务端API
Tomcat从7.0.5开始支持WebSocket,并实现了Java WebSocket规范。
Java WebSocket应用由一系列的Endpoint组成。Endpoint是一个Java对象,代表了WebSocket链接的一端。
(例如,某用户用浏览器和服务端建立了websocket连接之后,服务器就会为该用户创建一个自己的Endpoint。即服务端会有和每个客户端一一对应的Endpoint)
所以,对于服务端来说,Endpoint可以视为是处理客户端具体websocket消息的一个接口,专门和某一个浏览器建立一对一的关系,处理其发送的消息,并返回消息等。
Endpoint对象在Websocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。
通常用注解式方式实现Endpoint,即定义一个POJO,并添加@ServerEndpoint相关注解。
在Endpoint接口中定义了与其生命周期相关的方法,注解式实现如下:
- @OnOpen:当开启一个新的会话时调用,该方法是客户端与服务端握手成功后调用的方法
- @OnClose:当会话关闭时调用
- @OnError:当连接过程异常时调用
了解了Endpoint生命周期,接下来要开始数据传输了!
服务端接收客户端发送的数据:
定义Endpoint时,用@OnMessage注解指定接收消息的方法,收到消息后会自动执行;
服务端推送数据给客户端:
发送消息由RemoteEndpoint完成,其实例由Session维护。
发送消息有同步和异步两种方式:
同步:通过session,getBasicRemote获取同步消息发送的实例,然后调用其sendXxx()方法发送消息
异步:通过session,getAsyncRemote获取异步消息发送实例,然后调用其sendXxx()方法发送消息
(注:如sendText()就是发送文本数据)
@ServerEndpoint("/chat")
@Component
public class ChatEndpoint{@OnOpen//连接建立时被调用public void onOpen(Session session, EndpointConfig config){}@OnMessage//接收客户端发送的数据时被调用public void Message(String message){}@OnClose//连接关闭时调用public void onClose(Session session){}
}
Web浏览器和服务器建立websocket连接之后,OnOpen事件就会触发,onOpen方法就会自动执行。Tomcat会解析这些注解,然后传递onOpen方法中的参数。
实现小小聊天室
实现流程

- ws client:为客户端组件,即浏览器;login页面输入用户名密码登录后,会请求UserController里的方法;登录成功后,浏览器会向服务端发送websocket请求,触发OnOpen事件;在发送消息时,将消息推送到服务器端,触发OnMessage事件;当关闭连接时,触发OnClose事件;
- UserController:用于登录请求的接收,校验用户名密码是否正确;用户名不为空即可,密码要求为123;登录成功后跳转到聊天室页面;
- @OnOpen:OnOpen事件被触发后,在该方法中要记录session和httpsession,并广播消息;因为登录并建立会话之后,需要通知其他用户我已登录,并把最新的用户列表推送给所有的客户端;
- @OnMessage:OnMessage事件被触发后,需要解析消息,并判断收消息的人是谁,最后把消息推送给指定的人;
- @OnClose:Onclose事件被触发后,断开与客户端的连接。
消息格式
消息均为Json格式,分为客户端推送给服务端的消息,以及服务端返回客户端的消息。服务端发往客户端的消息又分两种:一种是系统消息,如显示所有好友信息;另一种是推送给用户的消息,即聊天消息。
客户端–>服务端
消息格式:{“toName”:“刘能”, “message”:“你好”}
服务端–>客户端
- 系统消息格式:{“system”:true, “fromName”:null, “message”:[“好友1”,“好友2”]}
- 推送给某一个用户的消息格式:{“system”:false, “fromName”:刘能, “message”:“你好”}
相关文章:
SocketWeb实现小小聊天室
SocketWeb实现小小聊天室 消息推送的常见方式轮询长轮询SSE(server-sent event):服务器发送事件WebSocketWebSocket简介WebSocket API 实现小小聊天室实现流程消息格式客户端-->服务端服务端-->客户端 消息推送的常见方式 轮询 浏览器…...
如何在启用Secure Boot的Ubuntu 22.04电脑中安装使用VirtualBox 6.1
我使用的是华为Matebook X Pro笔记本电脑,默认开启了UEFI安全引导(UEFI Secure Boot),安装了Windows和Ubuntu双操作系统,平时基本上都是使用Ubuntu 22.04(Linux Mint 21.3),使用上也…...
基于B/S+MySQL+Tomcat开发的旅游信息管理系统
基于B/SMySQLTomcat开发的旅游信息管理系统 项目介绍💁🏻 塞北村镇旅游网站设计主要用于实现旅游景点信息管理,基本功能包括:主界面模块设计,用户注册模块,旅游景点模块,酒店预订模块࿰…...
mac m3安装nvm安装说明;mac安装xbrew
安装说明说明: 1.安装brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"2.安装nvm brew install nvm3.创建.nvm目录 mkdir ~/.nvm4.编辑 ~/.zshrc 配置文件 vi ~/.zshrc5.在 ~/.zshrc 配置文件内添加内…...
【小沐学QT】QT学习之Web控件的使用
文章目录 1、简介1.1 Qt简介1.2 Qt下载和安装1.3 Qt快捷键1.4 Qt帮助 2、QtWeb控件2.1 测试代码1(QApplication)2.2 测试代码2(QApplicationQWidget)2.3 测试代码3(QApplicationQMainWindow)2.4 测试代码4&…...
word embedding
介绍: ASCII可以编码为计算机可以识别的数据,为什么还需要embedding? 计算机只是对“字母”进行ASCII编码,并没有对词汇的“Word”编码。词汇应该是咱们处理自然语言的最基本的元素,而不是字母。那么世界上有千千万万的Word&am…...
原码,反码,补码
原码 什么是原码 原码:十进制数据的二进制表现形式,最左边是符号位,0为正,1为负 最大值 0 1 1 1 1 1 1 1 > 127 最小值 1 1 1 1 1 1 1 1 > -127 原码的弊端 利用原码对正数进行计算是不会有问题的 但是如果是负数计算…...
科技赋能,MTW400A为农村饮水安全打通“最后一公里”
日前,山东省政府纵深推进国家省级水网先导区建设,持续深化“水网”行动,着力构筑水安全保障网、水民生服务网、水生态保护网,建设水美乡村示范带、内河航运示范带、文旅融合示范带、绿色发展示范带,推动形成“三网四带…...
测试计划、测试方案、测试策略、测试用例的区别
一 测试计划 测试计划是指描述了要进行的测试活动的范围、方法、资源和进度的文档。它主要包括测试项、被测特性、各阶段的测试任务、时间进度安排,谁执行任务和风险控制等,可以包括测试策略。 二 测试方案 测试方案是指描述需要测试的特性、测试的方…...
c# 异常处理
异常类 .NET Framework 类库中的所有异常都派生于 Exception 类,异常包括系统异常和应用异常。 默认所有系统异常派生于 System.SystemException,所有的应用程序异常派生于 System.ApplicationException。 系统异常一般不可预测,比如内存堆…...
(delphi11最新学习资料) Object Pascal 学习笔记---第6章第3节(传递字符串作为参数)
6.3 字符串数据类型 Object Pascal 中的字符串数据类型比简单的字符数组复杂得多,其功能远远超出了大多数编程语言为类似数据类型提供的功能。在本节中,我将介绍这种数据类型背后的关键概念;在接下来的章节中,我们将更详细地探…...
k8s节点负载使用情况分析命令kubectl describe node [node-name]
1.到任意安装了kubectl节点命令的节点上执行kubectl describe node [node-name] 上面的Requests最小分配 Limits最大分配是所有pod之和,最小分配之和不能超过服务器实际参数,否则新的pod会因为资源不够起不来,最大分配是预设之和࿰…...
自动驾驶加速落地,激光雷达放量可期(上)
1 激光雷达应用广泛,汽车有望成最大催化 激光雷达(LiDAR)是一种主动遥感技术,通过测定传感器发出的激光在传感器与目标物体之间的传播距离,来分析目标地物表面的反射能量大小、反射波谱的幅度、频率和相位等信息&#…...
变量的间接引用
场景: 如果第一个变量的值是第二个变量的名字,我们能够从第一个变量中取得第二个变量的值吗?例如,如果aztj且ztjz,那么我们能够通过引用变量a来获得值z吗?答案是可以,它被称为间接引用…...
学习JAVA的第六天(基础)
目录 集合 集合和数组的对比 ArrayList成员方法 ArrayList成员方法代码展示 练习 集合的遍历01之字符串 集合的遍历02之数字 集合的遍历03之学生对象 集合 集合和数组的对比 从长度维度来看 数组长度固定 集合长度可变从存储类型维度来看 数组可以存放基本数据类型和…...
LeetCode 2673.使二叉树所有路径值相等的最小代价:自顶向下的DFS 或 自底向上的递推
【LetMeFly】2673.使二叉树所有路径值相等的最小代价:自顶向下的DFS 或 自底向上的递推 力扣题目链接:https://leetcode.cn/problems/make-costs-of-paths-equal-in-a-binary-tree/ 给你一个整数 n 表示一棵 满二叉树 里面节点的数目,节点编…...
9、电源管理入门之CPU Idle
目录 1. CPU Idle有什么用? 2. CPU Idle整体框架 3. Idle状态判断 3. cpuidle core 4. 注册初始化 4.1 cpuidle governor注册 4.2 cpuidle driver注册 4.3 cpuidle device注册 5. cpuidle触发流程 关于Linux的很多知识其实网上的资料非常的多,但是也有些问题: 有时…...
uniapp的扩展组件uni-popup 弹出层自动打开
我的需求是在页面加载完之后自动打开弹窗,自动打开只能写在onReady 或 mounted 生命周期内,这是这个组件的规定: 如果想在页面渲染完毕后就打开 uni-popup ,请在 onReady 或 mounted 生命周期内调用,确保组件渲染完毕…...
二、mysql常用函数
目录 一、Mysql数值型函数 二、Mysql字符串函数 三、Mysql日期和时间函数 四、Mysql聚合函数 五、Mysql流程控制函数 六、其他函数 一、Mysql数值型函数 函数名称 作用 abc 求绝对值 sqrt 求二次方根 mod 求余数 ceil 和 ceiling 功能一样,都是返回不小…...
【Redis | 第一篇】快速了解Redis
文章目录 1.快速了解Redis1.1简介1.2与其他key-value存储的不同处1.3Redis安装——Windows环境1.3.1下载redis1.3.2启动redis1.3.3进入redis客户端1.3.4修改配置 1.4Redis安装——Linux环境1.4.1安装命令1.4.2启动redis1.4.3进入redis客户端 1.5配置修改1.6小结 1.快速了解Redi…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
