WebScoket-服务器客户端双向通信

WebScoket学习笔记


1. 消息推送常用方式介绍

轮询

浏览器以指定的时间间隔向服务器发出HTTP请求,服务器实时返回数据给浏览器。

image-20250109103523290

长轮询

浏览器发出ajax请求,服务器端接收到请求后,会阻塞请求直到有数据或者超时才返回。

image-20250109103936370

SSE

server-sent-event:服务器发送事件

SSE是在服务器和客户端之间打开一个单向通道,服务器通向客户端。

服务器响应的不再是一次性的数据包,而是text/event-stream类型的数据流信息。

服务器有数据变更时,将数据流式传输到客户端。

image-20250109104625870


2. WebSocket

2.1 介绍

WebSocket 是一种在基于TCP连接上进行全双工通信的协议。

说明:

  • 全双工:允许数据在两个方向上同时传输。
  • 半双工:允许数据在两个方向上传输,但是同一个时间段内只允许一个方向上传输。

image-20250109105530021

2.2 客户端API

websocket对象创建

```ts
let ws = new WebSocket(URL);
```

URL说明

  • 格式:协议://ip地址:端口/访问路径
  • 协议:协议名称为ws

websocket对象相关事件

事件 事件处理程序 描述
open ws.onopen 连接建立时
message ws.onmessage 客户端接受到服务器发送到数据时触发
close ws.onclose 连接关闭时触发
error ws.onerror 发生错误时触发

websocket对象提供的方法

send():通过websocket对象调用该方法发送数据给服务端。

```html

```

2.3 服务端API

Tomcat的7.0.5版本开始支持websocket,并且实现了Java websocket规范。

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

我们可以通过两种方式定义Endpoint:

  • 第一种是编程式,即继承类javax.websocket.Endpoint并实现其方法。
  • 第二种是注解式,即定义一个POJO,并添加@ServerEndpoint相关注解。

Endpoint实例在WebSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法,规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:

方法 描述 注解
onOpen() 当开启一个新的会话时调用,该方法是客户端与服务器端握手成功后调用的方法 @OnOpen
onClose() 当会话关闭时调用 @OnClose
onError() 当连接过程异常时调用 @OnError

服务器端接受客户端数据

  • 编程式

通过添加MessageHandler消息处理器来接收消息

  • 注解式

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

服务器端推送数据到客户端

发送消息则由RemoteEndpoint完成,其实例由Session维护。

发送消息有2种方式

  • 通过session.getBasicRemote获取同步消息发送的实例,然后调用其sendXXX()方法发送消息。
  • 通过session.getAsyncRemote获取异步消息发送实例,然后调用其sendXXX()方法发送消息。

    ```java
    @ServerEndpoint("/chat")
    @Component
    public class ChatEndpoint {
    @OnOpen
    public void onOPen(Session session,EndPointConfig config){

    }

    @OnMessage
    public void onMessage(String message){

    }

    @OnClose
    public void onClose(Session session){

    }
    }
    ```

3. 总结

新建SpringBoot项目,导入依赖:

```xml

  org.springframework.boot
  spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-websocket

```

编写配置类,扫描所有添加@ServerEndpoint注解的Bean

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

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

```java
@Configuration
public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        HttpSession session = (HttpSession) request.getHttpSession();
        // 将HttpSession对象存储到配置对象中
        sec.getUserProperties().put(HttpSession.class.getName(), session);
    }
}
```

@ServerEndpoint注解中引入配置器

```java
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
```

创建ChatEndPoint

```java
@Component
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
public class ChatEndpoint {
    private static final Map onlineUsers = new ConcurrentHashMap<>();
    private HttpSession httpSession;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());

    }
    public void broadcastAllUser(){

    }
    @OnMessage
    public void onMessage(String message, Session session) {

    }
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {

    }
}
```

服务器向客户端发送消息:

```java
session.getAsyncRemote().sendText("...");
```

客户端向服务器发送消息:

```java
let ws = new WebSocket("ws://localhost:8080/chat")
ws.send("xxx");
```

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/6615.html

(0)
LomuLomu
上一篇 2025 年 1 月 16 日 上午12:59
下一篇 2025 年 1 月 16 日 上午1:29

相关推荐

  • Python 潮流周刊#85:让 AI 帮你写出更好的代码(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进 Python 技术,并增长职业和副业的收入。 分享了 12 篇文章,12 个开源项目,1 则音视频,全文 2300 字。 以下是本期摘要: 🦄文章&教程 ① 如果一直要求 LLM “写出更…

    未分类 2025 年 1 月 13 日
    38700
  • 促销系统:促销活动、优惠券、优惠规则概念模型设计

    大家好,我是汤师爷~ 概念模型设计是促销系统开发的关键环节,我们需要基于之前的功能分析,将复杂的促销业务拆解成清晰的领域概念,这些概念之间的关系界定和边界划分,将直接决定系统的可维护性和扩展性。 促销系统核心概念模型 通过对促销业务的分析,我们可以抽象出促销系统的关键概念模型。 1、促销活动模型 促销活动模型对活动的各个要素和规则进行抽象,包含活动名称、描述…

    2025 年 1 月 6 日
    41600
  • JVM虚拟机监控及性能调优实战

    大家好,欢迎来到 程序视点!我是小二哥。 今天我们再来聊聊jvisualvm 目录 jvisualvm介绍 代码语言:txt 复制 “` 1. jvisualvm是JDK自带的可以远程监控内存,跟踪垃圾回收,执行时内存,CPU/线程分析,生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。 “` jvisualvm使用 …

    2025 年 1 月 17 日
    32900
  • 【Java 学习】Java的生命之源:走进Object类的神秘花园,解密Object类的背后故事

    💬 欢迎讨论:如对文章内容有疑问或见解,欢迎在评论区留言,我需要您的帮助! 👍 点赞、收藏与分享:如果这篇文章对您有所帮助,请不吝点赞、收藏或分享,谢谢您的支持! 🚀 传播技术之美:期待您将这篇文章推荐给更多对需要学习Java语言、低代码开发感兴趣的朋友,让我们共同学习、成长! 1. Object 类 1.1 为什么所有类都继承 Object 类? 在Jav…

    2025 年 1 月 10 日
    40200
  • Redis 爆高危漏洞,请速度修复。。

    大家好,我是R哥。 今天一早收到了腾讯云给我的【主机安全 】漏洞通知: 好家伙,大名鼎鼎的 Redis 爆高危漏洞了,R哥的题库「Java面试库」也用到了 Redis 来缓存面试题内容,所以这一下子就引起了我的警惕,赶紧看看什么鬼。 漏洞描述 下面是漏洞描述和修复说明: https://github.com/redis/redis/security/advi…

    2025 年 1 月 6 日
    38000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信