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

如何使用Java WebSocket API实现客户端和服务器端的通信?

WebSocket相关的方法主要涉及客户端和服务器端,以下是对其几个关键方法之间关联以及参数传递方式的介绍:

服务器端

Java中通常使用Jakarta WebSocket API(以前是Java EE的一部分,现在Jakarta EE 继续维护 )来实现WebSocket服务器端功能,常用注解有@ServerEndpoint, 关键方法包括:

  • onOpen(Session session):当客户端与服务器成功建立WebSocket连接时,该方法会被调用。
    • 方法关联:它是连接建立后的第一个触发方法,为后续的数据交互等操作做准备。通过它可以获取到代表该连接的 Session 对象,后续对连接的操作,如发送消息等,都依赖于这个 Session
    • 参数传递Session 参数由WebSocket容器在连接建立时自动创建并传递,它包含了与该连接相关的各种信息,如远程地址、请求头、发送消息的方法等。例如,你可以通过 session.getRemoteAddress() 获取客户端的远程地址。
  • onMessage(String message, Session session):当服务器接收到客户端发送的文本消息时会调用此方法(如果处理二进制消息,有对应的 onMessage(byte[] message, Session session) 方法 )。
    • 方法关联:它依赖于 onOpen 方法建立的连接,只有在连接成功建立后,才会接收并处理客户端发送的消息。在处理完消息后,也可以通过传入的 Session 对象向客户端发送响应消息。
    • 参数传递message 参数是客户端实际发送的文本内容,由WebSocket容器从网络传输数据中解析出来并传递。session 依然是代表该连接的会话对象,与 onOpen 方法中的 session 是同一个实例,用于在处理消息过程中操作连接,比如 session.getBasicRemote().sendText("Response message"); 向客户端发送响应文本消息。
  • onClose(Session session, CloseReason closeReason):当WebSocket连接关闭时调用,无论是正常关闭还是异常关闭。
    • 方法关联:它是连接生命周期的最后阶段,在连接关闭时触发,用于进行一些资源清理、状态更新等操作。
    • 参数传递session 是即将关闭的连接会话对象。closeReason 由WebSocket容器根据连接关闭的情况生成并传递,包含了关闭的状态码和关闭原因描述,比如 closeReason.getCloseCode().getCode() 可以获取关闭状态码,closeReason.getReasonPhrase() 获取关闭原因描述。
  • onError(Session session, Throwable throwable):当WebSocket连接在处理过程中发生错误时调用。
    • 方法关联:它与其他方法在异常情况下产生关联,一旦在消息处理、连接建立等过程中出现异常,就会触发此方法。可以在该方法中记录错误日志,根据情况关闭连接等。
    • 参数传递session 是出现错误的连接会话对象。throwable 是具体的异常对象,包含了异常类型和堆栈信息等,通过 throwable.printStackTrace() 可以打印出异常堆栈信息以便排查问题。

客户端

使用 StandardWebSocketClient 等类来实现WebSocket客户端功能,关键方法有:

  • connectToServer(Endpoint endpoint, URI uri):用于发起WebSocket连接。
    • 方法关联:它是客户端建立连接的入口方法,后续的消息接收、发送等操作都依赖于成功建立的连接。
    • 参数传递endpoint 是一个实现了 Endpoint 接口的类实例,包含了处理连接的回调方法,如 onOpenonMessage 等。uri 是要连接的WebSocket服务器的地址,格式为 ws://wss:// 开头。例如:
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
MyEndpoint myEndpoint = new MyEndpoint();
URI serverUri = new URI("ws://localhost:8080/your - websocket - path");
container.connectToServer(myEndpoint, serverUri);

其中 MyEndpoint 是自定义的实现了 Endpoint 接口的类。

  • sendText(String text)(在 Session 对象上调用 ):用于向服务器发送文本消息。
    • 方法关联:依赖于 connectToServer 方法成功建立的连接,只有在连接建立后才能发送消息。
    • 参数传递text 是要发送的文本内容,由客户端程序指定,然后通过WebSocket协议发送到服务器端。

通过这些方法的相互协作,实现了WebSocket的全双工通信功能,不同方法之间通过 Session 等对象以及参数传递来协同工作。


以下是基于该API的详细实现步骤,包含服务器端和客户端的代码示例及核心原理说明。

一、服务器端实现(核心步骤)

服务器端需要定义一个WebSocket端点(Endpoint),用于处理客户端的连接、消息接收、连接关闭等事件。主要通过注解或继承Endpoint类实现,推荐使用注解方式(更简洁)。

1. 依赖准备

若使用Maven,需添加Java EE WebSocket依赖(Java 7+支持,Java EE 7及以上内置):

<dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version><scope>provided</scope> <!-- 容器(如Tomcat 8+)已内置,无需打包 -->
</dependency>
2. 定义WebSocket端点类

通过@ServerEndpoint注解标记端点,并指定访问路径(如/chat),同时实现核心事件方法:

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;@ServerEndpoint("/chat") // 客户端连接的URL:ws://localhost:8080/项目名/chat
public class ChatServer {// 存储所有连接的客户端会话(线程安全集合)private static CopyOnWriteArraySet<Session> sessions = new CopyOnWriteArraySet<>();private Session session; // 当前客户端的会话/*** 客户端连接成功时触发*/@OnOpenpublic void onOpen(Session session) {this.session = session;sessions.add(session); // 将新会话加入集合System.out.println("新客户端连接,当前在线:" + sessions.size());}/*** 收到客户端消息时触发*/@OnMessagepublic void onMessage(String message, Session session) throws IOException {System.out.println("收到消息:" + message + "(来自会话:" + session.getId() + ")");// 广播消息给所有在线客户端for (Session s : sessions) {if (s.isOpen()) { // 确保会话未关闭s.getBasicRemote().sendText("服务器转发:" + message); // 同步发送消息// s.getAsyncRemote().sendText("异步发送:" + message); // 异步发送(非阻塞)}}}/*** 客户端连接关闭时触发*/@OnClosepublic void onClose(Session session, CloseReason reason) {sessions.remove(session); // 从集合中移除会话System.out.println("客户端断开连接,原因:" + reason.getReasonPhrase() + ",当前在线:" + sessions.size());}/*** 通信发生错误时触发*/@OnErrorpublic void onError(Session session, Throwable error) {System.out.println("发生错误:");error.printStackTrace();}
}

二、客户端实现(Java客户端)

Java客户端可通过WebSocketContainer创建连接,与服务器端通信。需注意:客户端API在Java EE中也有定义,或可使用第三方库(如Tyrus,JSR 356的参考实现)。

1. 客户端依赖(若需独立运行)

若使用Tyrus作为客户端(适合非Web容器环境),添加Maven依赖:

<dependency><groupId>org.glassfish.tyrus.bundles</groupId><artifactId>tyrus-standalone-client</artifactId><version>1.17</version>
</dependency>
2. 客户端代码实现
import javax.websocket.*;
import java.net.URI;@ClientEndpoint // 标记为客户端端点
public class ChatClient {private Session session; // 与服务器的会话/*** 连接服务器*/public void connect(String serverUri) throws Exception {WebSocketContainer container = ContainerProvider.getWebSocketContainer();container.connectToServer(this, new URI(serverUri)); // 连接到服务器端点}/*** 连接成功时触发*/@OnOpenpublic void onOpen(Session session) {this.session = session;System.out.println("与服务器连接成功,会话ID:" + session.getId());try {session.getBasicRemote().sendText("客户端已连接"); // 向服务器发送消息} catch (IOException e) {e.printStackTrace();}}/*** 收到服务器消息时触发*/@OnMessagepublic void onMessage(String message, Session session) {System.out.println("收到服务器消息:" + message);// 可在此处处理消息(如回复、业务逻辑)}/*** 连接关闭时触发*/@OnClosepublic void onClose(Session session, CloseReason reason) {System.out.println("与服务器断开连接,原因:" + reason.getReasonPhrase());}/*** 发生错误时触发*/@OnErrorpublic void onError(Session session, Throwable error) {System.out.println("客户端错误:");error.printStackTrace();}/*** 向服务器发送消息*/public void sendMessage(String message) throws IOException {if (session != null && session.isOpen()) {session.getBasicRemote().sendText(message);}}// 测试客户端public static void main(String[] args) throws Exception {ChatClient client = new ChatClient();client.connect("ws://localhost:8080/your-project/chat"); // 服务器端点URL// 模拟发送消息client.sendMessage("Hello, Server!");// 保持连接(实际应用中需根据业务处理)Thread.sleep(30000);}
}

三、核心概念与参数传递说明

  1. Session(会话)

    • 服务器端和客户端均通过Session对象标识一个连接,包含连接的元数据(如ID、是否打开)。
    • 消息发送通过SessiongetBasicRemote()(同步)或getAsyncRemote()(异步)实现。
  2. 消息传递

    • 服务器端@OnMessage方法接收客户端消息,参数message为消息内容(支持Stringbyte[]ByteBuffer等类型)。
    • 客户端通过ws.send()(JS)或session.getBasicRemote().sendText()(Java)发送消息,服务器端接收后可转发给其他客户端(如示例中的广播逻辑)。
  3. 生命周期方法关联

    • @OnOpen → 连接建立时触发,Session对象在此处初始化并加入管理集合。
    • @OnMessage → 依赖@OnOpen中初始化的Session进行消息转发。
    • @OnClose/@OnError → 清理Session资源,确保集合中只保留活跃连接。

四、部署与测试

  1. 服务器端部署到支持WebSocket的容器(如Tomcat 8+、Jetty 9+),启动后访问ws://localhost:8080/项目名/chat
  2. 运行Java客户端或浏览器客户端,输入消息即可实现双向通信。
http://www.dtcms.com/a/272575.html

相关文章:

  • 蓝桥杯第十六届(2025)真题深度解析:思路复盘与代码实战
  • MinerU将PDF转成md文件,并分拣图片
  • Alibaba Druid主要配置
  • 图片合并pdf
  • 新手向:实现ATM模拟系统
  • TDengine 数据库建模最佳实践
  • Oracle 视图
  • Tomcat:Java Web应用的幕后英雄
  • 线性探针是什么:是一种用于探测神经网络中特定特征的工具
  • 从零开始搭建深度学习大厦系列-3.卷积神经网络基础(5-9)
  • 李宏毅(深度学习)--(2)
  • 数据库复合索引设计:为什么等值查询列应该放在范围查询列前面?
  • 区间动态规划详解
  • 【JMeter】跨线程组传递参数
  • 在Docker中运行macOS的超方便体验!
  • SpringAI×Ollama:Java生态无缝集成本地大模型实践指南
  • Redis数据库基础概述
  • 8.2.3希尔排序
  • Spring for Apache Pulsar->Reactive Support->Message Production
  • KV Cache原理详解 + 代码理解
  • 从零实现一个GPT 【React + Express】--- 【2】实现对话流和停止生成
  • Pytest之收集用例规则与运行指定用例
  • 外贸网站模板 网页设计模板网站
  • WinUI3入门17:本地文件存储LocalApplicationData在哪里
  • 【佳易王桌球棋牌计时计费软件】:从功能到实操的全方位解析,灯控器适配、会员管理多场景,软件程序操作教程详解
  • BatchNorm解决梯度消失/爆炸
  • van-tabs 自定义
  • 08-自然壁纸实战教程-视频列表-云
  • softmax公式推导
  • 深度学习中的批处理vs小批量训练