黑马 - websocket搭建在线聊天室

这里写自定义目录标题

  • 一、消息推送常见方式
  • 二、websocket 是什么?
  • 三、websocket api的介绍
    • 1、客户端 (浏览器)
  • 四、实现在线聊天室
    • 1、需求
    • 2、聊天室流程分析
    • 3、消息格式
    • 4、代码实现

一、消息推送常见方式

1、轮训方式
在这里插入图片描述

2、SSE(server-send event)服务器发送事件
在这里插入图片描述

3、websocket

二、websocket 是什么?

websocket 是一种基于TCP 连接上进行全双工通信的协议
在这里插入图片描述
在这里插入图片描述

三、websocket api的介绍

1、客户端 (浏览器)

  • websocket对象创建
    在这里插入图片描述

  • websocket对象相关事件
    在这里插入图片描述

  • websocket 对象提供的方法
    在这里插入图片描述


## 2、服务端api Tomcat 的7.0.5版本开始支持 websocket , 并且实现了Java websocket 规范。

Java websocket 应用由一系列的 Endpoint组成。
Endpoint 是一个java对象,代表websocket连接的一段。对于服务端,我们可以视其为处理具体websocket消息的接口

我们可以通过两种方式定义EndPoint:
编程式,继承类 javax.websocket.Endpoint 并实现其方法
注解式,定义一个pojo,并添加@ServerEndPoint相关注解

在这里插入图片描述

  • 服务端如何接收客户端发过来的数据呢?

    • 编程式
      通过添加MessageHandler消息处理器来接收消息

    • 注解式
      在定义endpoint时,通过@OnMessage 注解指定接收消息的方法

  • 服务器如何推送消息给客户端
    发送消息由RemoteEndpoint完成,其实例由Session维护。
    在这里插入图片描述
    在这里插入图片描述

四、实现在线聊天室

1、需求

通过websocket实现在线聊天室

2、聊天室流程分析

在这里插入图片描述

3、消息格式

在这里插入图片描述

4、代码实现

1) 引入依赖

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

2)编写配置类

扫描所有添加 @ServerEndpoint注解的Bean

@Configuration
public class WebsocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

编写配置类,用于获取 HttpSession 对象

public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator {/*** @param sec* @param request  握手请求* @param response*/@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {// 获取HttpSession对象HttpSession httpSession = (HttpSession) request.getHttpSession();// 将 HttpSession对象保存起来sec.getUserProperties().put(HttpSession.class.getName(), httpSession);}
}

在@ServerEndpoint 注解中引入配置器 @ServerEndpoint(value = “/chat”, configurator = GetHttpSessionConfig.class)

@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)
@Component
public class ChatEndpoint {/*** 使用static* ChatEndpoint是多例的,多个实例共享一个Map对象*/private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();private HttpSession httpSession;@OnOpenpublic void onOpen(Session session, EndpointConfig endpointConfig) {this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName());String userName = (String) httpSession.getAttribute("user");// 1、将我们的session进行保存onlineUsers.put(userName, session);// 2、广播消息,将登录的用户推送给所有的用户String message = MessageUtils.getMessage(true, null, userName + "上线");boardcast(message);// 3、}/*** 广播消息*/private void boardcast(String message) {// 遍历 map 集合Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();for (Map.Entry<String, Session> entry : entries) {Session session = entry.getValue();try {session.getBasicRemote().sendText(message);} catch (IOException e) {// 记录日志}}}/*** 浏览器发送消息到服务端,该方法会被调用*/@OnMessagepublic void onMessage(String message, EndpointConfig endpointConfig) {try {this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName());String fromName = (String) httpSession.getAttribute("user");// 将消息推送给指定的用户   message : {"toName":"张三","message":"你好"}ClientMessage message1 = JSON.parseObject(message, ClientMessage.class);String toName = message1.getToName();Session session = onlineUsers.get(toName);String message2 = MessageUtils.getMessage(false, fromName, message1.getMessage());session.getBasicRemote().sendText(message2);} catch (IOException e) {throw new RuntimeException(e);}}/*** 当websocket连接断开时,此方法会被处罚*/@OnClosepublic void onClose(Session session, EndpointConfig endpointConfig) {// 从在线用户集合中剔除断开连接的用户this.httpSession = (HttpSession) endpointConfig.getUserProperties().get(HttpSession.class.getName());String userName = (String) httpSession.getAttribute("user");onlineUsers.remove(userName);// 通知其他用户当前用户下线String message = MessageUtils.getMessage(true, null, userName + "上线");boardcast(message);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/5653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EasyDarwin录像存储

目录 1、安装ffmpeg 2、建立录像存储路径 3、修改EasyDarwin配置文件 4、测试 (1)推流&#x

2024年第二十一届 五一杯 (A题)大学生数学建模挑战赛 | 多目标优化问题,深度学习分析 | 数学建模完整代码解析

DeepVisionary 每日深度学习前沿科技推送&顶会论文&数学建模与科技信息前沿资讯分享&#xff0c;与你一起了解前沿科技知识&#xff01; 本次DeepVisionary带来的是五一杯的详细解读&#xff1a; 完整内容可以在文章末尾全文免费领取&阅读&#xff01; 第一个问题…

【Linux】进程终止

思维导图 学习内容 进程终止是进程控制里面的一个重要的知识&#xff0c;通过这一篇博客&#xff0c;我们可以学习到进程终止的概念&#xff0c;进程终止的三种情况&#xff0c;进程终止的退出码和退出信号&#xff0c;最后在来学习进程是如何进行终止的。 学习目标 进程终止…

诺基亚贝尔探访上海斯歌,共探创新合作新机遇

近日&#xff0c;上海斯歌K2 BPM迎来重要客户考察交流活动。来自诺基亚贝尔的首席数字官刘少勇一行莅临了上海斯歌K2 BPM 的武汉研发中心&#xff0c;并对上海斯歌在BPM业务流程管理领域的研发成果及交付能力给予了高度肯定。 此次活动不仅加深了双方的战略合作&#xff0c;也为…

维修家政按摩到家上门小程序开源版开发

维修家政按摩到家上门小程序开源版开发 智能定位&#xff0c;精准计费——全新上门服务平台功能解析。 全新上门服务平台已经上线&#xff0c;它拥有一系列强大的功能&#xff0c;旨在为用户提供最便捷、最个性化的服务体验。 !](https://img-blog.csdnimg.cn/direct/86195e…

Linux 查看主机内存,CPU使用率的两种推荐指令top ,free 指令解读

top 指令 top 指令是 Linux 系统中一个实时显示系统状态的动态视图工具&#xff0c;主要用于监控系统的整体运行状态&#xff0c;包括CPU使用率、内存使用情况、运行中的进程信息等。它是一个非常强大的命令行工具&#xff0c;常用于性能分析和故障排查。下面是一些基本的使用…

【QEMU系统分析之实例篇(八)】

系列文章目录 第八章 QEMU系统仿真的机器创建分析实例 文章目录 系列文章目录第八章 QEMU系统仿真的机器创建分析实例 前言一、QEMU是什么&#xff1f;二、QEMU系统仿真的机器创建分析实例1.系统仿真的命令行参数2.目标机器创建过程3.输出分析 总结 前言 本文以 QEMU 8.2.2 为…

WCH RISC CH32V303RCT6 单片机的SDI Printf 虚拟串口功能 类似SEGGER RTT打印功能 简单分析

参考&#xff1a; 有关于 SDI printf 更多的信息和资料吗&#xff1f; 关于 CH32 系列 MCU SDI 虚拟串口功能的使用 【CH32X035 评估板测评】 教你使用 SDI 接口重定向 printf SDI (Serial Data Interface) 是沁恒微电子 RISC-V 内核的私有外设接口,CH32 RISC-V 系列目前提供了…

掌握技巧:Linux下通过命令查看系统时间

在Linux系统中&#xff0c;系统时间是至关重要的。程序员经常需要查看系统时间来进行调试、日志记录以及任务调度等操作。 虽然大多数Linux发行版都提供了图形化界面来查看系统时间&#xff0c;但是使用命令行来获取系统时间更加高效和便捷。 本文将介绍几种在Linux下通过命令…

redis 高可用 Sentinel 详解

写在前面 redis 在我们日常的业务开发中是十分常见的&#xff0c;而redis的可用性就必须要有很高的要求&#xff0c;那么 redis集群的高可用由有一个或者多个 Sentinel(哨兵) 实例组成的 哨兵系统来保证的。 哨兵 由一个或者多个 Sentinel 实例组成的 Sentinel 系统可以监控任…

CRC32 循环冗余校验

实现的CRC-32算法&#xff0c;Java编写&#xff0c;使用二进制异或相除法实现。 public static int CRC322(final byte[] _bytes) {// 补充32位0byte[] bytes new byte[_bytes.length 4];System.arraycopy(_bytes, 0, bytes, 0, _bytes.length);// CRC初始值Bits crc Bits.v…

53.HarmonyOS鸿蒙系统 App(ArkTS) socket套接字连接失败无效参数--invalid argument

ark ts socket套接字连接失败无效参数--invalid argument 绑定本机真实连接的WIFI的IP&#xff0c;不要绑定127.0.0.1

MySQL:DQL语句和多表设计

DQL Data Query Language(数据查询语言) 用来查询数据库中表的记录 查询关键字:SELECT 在业务系统中,查询频次是远高于增删改的. 语法 SELECT #字段列表(基本查询) From #表名列表 WHERE #条件列表(条件查询) GROUP BY #分组字段列表(分组查询) HAVING #分组后条件列表 O…

C# 程序启动另外一个exe的时候传参数

C# 程序启动另外一个exe的时候传参数 一、传递一个参数 using System.Diagnostics;public void StartAnotherProcessWithArguments() {// 创建ProcessStartInfo实例ProcessStartInfo startInfo new ProcessStartInfo();// 设置要执行的程序路径startInfo.FileName "C:…

VS code 同步odata服务

在做UI5得开发过程中&#xff0c;经常会出现odata需要更新 那么已经加载过得项目如何去跟新odata服务呢 可以通过如下步骤 1.右键打开应用信息 2.找到manage service models 3.点击编辑 4.选中 刷新并保存

《STM32 HAL库》中断相关函数详尽解析——NVIC

观前提醒&#xff1a;本文以外部中断点灯为例&#xff0c;分析了HAL库中中断服务相关函数的使用及相互关联、底层原理 一、实例实现 实例简介&#xff1a;主函数控制LED2进行闪烁&#xff0c;中断控制LED0开关 我们先使用CubeMX创建项目文件&#xff1a; 1、在System Core中配…

逃逸分析学习

逃逸分析&#xff1a;一种确定指针动态范围的静态分析&#xff0c;它可以分析程序在哪些地方访问到指针。 场景一&#xff1a; ​ 对象被复制给成员变量或静态变量&#xff0c;可能被外部使用&#xff0c;此时变量就发生了逃逸。 场景二&#xff1a; ​ 对象通过return语句…

XY_RE复现(五)

一&#xff0c;给阿姨倒一杯卡布奇诺 是一道魔改TEA加密 给出了一些初始化&#xff0c;然后输入的flag拆分&#xff0c;两两一组&#xff0c;通过for循环放入encrypt加密函数 #include <stdio.h> #define uint32_t unsigned intvoid decrypt(uint32_t *v, uint32_t *ke…

【STM32F407+CUBEMX+FreeRTOS+lwIP netconn UDP TCP记录】

STM32F407CUBEMXFreeRTOSlwIP netconn UDP TCP记录 注意UDPUDP1UDP2 TCPTCP clientTCP server图片 注意 1、超时 #include “lwipopts.h” #define LWIP_SO_RCVTIMEO 12、先保证能ping通 3、关于工程创建可参考 【STM32F407CUBEMXFreeRTOSlwIP之UDP记录】 4、…

数据仓库Data Warehouse

数据仓库Data Warehouse 数仓是一种思想,数仓是一种规范,数仓是一种解决方案 1. 数据处理方式 数据处理大致可以分成两大类: 联机事务处理OLTP(on-line transaction processing)联机分析处理OLAP(On-Line Analytical Processing)1.1. OLTP OLTP的全称是On-line Transa…