首页 > 其他分享 >WebScoket-服务器客户端双向通信

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

时间:2025-01-15 10:22:25浏览次数:1  
标签:websocket 双向通信 session ws void WebScoket public 客户端

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对象创建

let ws = new WebSocket(URL);

URL说明

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

websocket对象相关事件

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

websocket对象提供的方法

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

<script>
    let ws = new WebSocket("ws://localhost:8080/chat")
    ws.onopen = function (){

    }
    ws.onmessage = function (evt) {
        console.log(evt)
    }
    ws.onclose = function () {

    }
    ws.onerror = function (){

    }
</script>

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()方法发送消息。
@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项目,导入依赖:

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

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

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

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

@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注解中引入配置器

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

创建ChatEndPoint

@Component
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
public class ChatEndpoint {
    private static final Map<String, Session> 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) {

    }
}

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

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

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

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

标签:websocket,双向通信,session,ws,void,WebScoket,public,客户端
From: https://www.cnblogs.com/mango0219/p/18671691

相关文章

  • WebScoket学习笔记
    WebScoket学习笔记1.消息推送常用方式介绍轮询浏览器以指定的时间间隔向服务器发出HTTP请求,服务器实时返回数据给浏览器。长轮询浏览器发出ajax请求,服务器端接收到请求后,会阻塞请求直到有数据或者超时才返回。SSEserver-sent-event:服务器发送事件SSE是在服务器和客户......
  • Termora跨平台 SSH/SFTP/Terminal 客户端工具
    前言Termora一款强大的终端模拟与SSH客户端工具,集SFTP传输、跨平台兼容、Zmodem协议、SSH端口转发、配置同步、宏录制、关键词高亮、密钥管理、多会话命令发送及数据加密于一体,专为追求高效远程工作的您设计。无论是开发、管理还是日常任务,Termora都能助您一臂之力,开启便捷、安全......
  • websocket-sharp:.NET平台上的WebSocket客户端与服务器开源库
    推荐一个C#开发的,实现WebSocket功能的开源项目。01项目简介websocket-sharp提供WebSocket客户端和服务器库,基于C#开发的,并遵循WebSocket协议规范,使得开发人员能够轻松地在.NET应用程序中实现WebSocket通信。websocket-sharp特色功能有:1、简洁易用的API:提供清晰且......
  • Git客户端(TortoiseGit)超全使用详解
    前言大家好,我是小徐啊。git是我们在开发Java应用的时候,要用到的代码版本管理工具。但是git本身自带的命令和gui工具,使用起来不是特别方便。TortoiseGit作为git的客户端,是一款非常实用的工具,能让我们以图形化的界面去操作git,今天就来介绍下TortoiseGit。文末附获取方式。如何使......
  • 开箱即用!一款支持多个大语言模型服务的桌面客户端!
    大家好,我是Java陈序员。可以说现在AI给我们的生活、工作带来了极大的便利,各种大语言模型层出不穷,功能多样。今天,给大家介绍一款支持多模型服务的桌面客户端,开箱即用!关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。项目介绍Ch......
  • 如何在ASP页面中判断客户端浏览器是否为移动设备,并进行相应的跳转?
    在ASP页面中,可以通过检查HTTP_USER_AGENT字符串来判断客户端浏览器是否为移动设备。如果检测到移动设备,则重定向到指定的移动端页面。以下是实现该功能的代码示例。为了SEO优化,问题标题已调整为更具描述性和关键词友好的形式。代码中已将具体的URL替换为“域名”,以适应不同的实际......
  • 网页应用从服务器主动推送到客户端有那些方式?
    网页应用从服务器主动推送到客户端的方式主要有以下几种:轮询(Polling):客户端不断向服务器发送请求询问是否有新数据。服务器返回新数据或表明无新数据。这种方式会造成很多无谓的请求,浪费带宽和服务器资源。长轮询(LongPolling):客户端向服务器发送请求后,服务器保持连接......
  • 请问如何在ASP页面中判断客户端浏览器是否为移动设备,并进行相应的跳转?
    问题描述:在ASP页面中,如何判断客户端浏览器是否为移动设备,并根据判断结果进行相应的页面跳转?答案:在ASP页面中,可以通过检查HTTP_USER_AGENT字符串来判断客户端浏览器是否为移动设备。如果检测到移动设备,则重定向到指定的移动端页面。以下是实现该功能的代码示例:<%'检查浏览器U......
  • Pulsar客户端如何控制内存使用
    摘要本文围绕一个常见的使用场景深入分析在高吞吐场景下,使用Pulsar客户端收发消息可能会遇到的若干问题。并以此为切入点,梳理一下Pulsar客户端在内存控制上所做的优化改进。使用场景假设这样一个常见的场景,一个搜索类业务需要记录用户搜索请求,以便后续分析搜索热点,以及有针对性......
  • [.NET] 使用客户端缓存提高API性能
    使用客户端缓存提高API性能摘要在现代应用程序中,性能始终是一个关键的考虑因素。无论是提高响应速度,降低延迟,还是减轻服务器负载,开发者都在寻找各种方法来优化他们的API。在Web开发中,利用客户端缓存是一种有效的方法,可以显著提高API的性能。本文将结合Replicant和Delta,深入探讨......