基于Jakarta的Java独立WebSocket服务器实现(Main.java启动)
基于Jakarta实现独立运行的Java WebSocket服务器(7*24小时接收数据流)
问题说明
我有一个正常运行的Java WebSocket客户端,会将原始数据流式转发到Java WebSocket服务器。需要实现纯Java的WebSocket服务器,满足以下要求:
- 7*24小时持续运行以收集数据
- 支持远程Java GUI访问数据
- 数据量和计算量较大,JavaScript服务器无法满足需求
- 技术栈限定为Jakarta,不需要基于JavaScript的聊天室类教程
现有代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tradeinsider</groupId> <artifactId>server</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> <!-- Jackson核心依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.18.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.18.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.18.2</version> </dependency> <!-- Jakarta WebSocket API --> <dependency> <groupId>jakarta.websocket</groupId> <artifactId>jakarta.websocket-api</artifactId> <version>2.2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.websocket</groupId> <artifactId>jakarta.websocket-client-api</artifactId> <version>2.2.0</version> <scope>provided</scope> </dependency> <!-- JSON处理依赖 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.11.0</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20241224</version> </dependency> <!-- 其他依赖 --> <dependency> <groupId>org.glassfish.tyrus.bundles</groupId> <artifactId>tyrus-standalone-client</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>9.1.0</version> </dependency> </dependencies> </project>
WebSocketEndpoint.java
package com.tradeinsider; import java.io.IOException; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; @ServerEndpoint("/ws") public class WebSocketEndpoint { @OnOpen public void onOpen(Session session) { System.out.println("WebSocket opened: " + session.getId()); } @OnMessage public void onMessage(String message, Session session) { System.out.println("Message received: " + message); } @OnClose public void onClose(Session session, CloseReason closeReason) { System.out.println("WebSocket closed: " + session.getId()); } @OnError public void onError(Session session, Throwable throwable) { System.out.println("WebSocket error: " + session.getId()); throwable.printStackTrace(); } }
Main.java
package com.tradeinsider; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public class Main { public static void main(String[] args) throws Exception { // 此处需要启动WebSocket服务器 } }
解决方案
1. 补充WebSocket服务器运行依赖
Jakarta WebSocket仅提供API规范,需要具体的服务器实现才能运行。在pom.xml中添加Tyrus(GlassFish官方WebSocket实现)的服务器依赖:
<!-- Tyrus WebSocket Server核心 --> <dependency> <groupId>org.glassfish.tyrus</groupId> <artifactId>tyrus-server</artifactId> <version>2.2.0</version> </dependency> <!-- Grizzly容器,用于运行Tyrus服务器 --> <dependency> <groupId>org.glassfish.tyrus</groupId> <artifactId>tyrus-container-grizzly</artifactId> <version>2.2.0</version> </dependency>
2. 修改Main.java启动WebSocket服务器
将Main类改为服务器启动入口,通过Tyrus启动独立运行的WebSocket服务器:
package com.tradeinsider; import org.glassfish.tyrus.server.Server; public class Main { public static void main(String[] args) { // 配置服务器地址(0.0.0.0允许外部访问)和端口 String host = "0.0.0.0"; int port = 8080; // 初始化服务器,指定WebSocket端点类 Server server = new Server(host, port, "/", null, WebSocketEndpoint.class); try { // 启动服务器 server.start(); System.out.println("WebSocket服务器已启动,访问地址:ws://" + host + ":" + port + "/ws"); System.out.println("服务器持续运行中,按Enter键停止..."); // 阻塞主线程,保持服务器运行 System.in.read(); } catch (Exception e) { throw new RuntimeException("启动WebSocket服务器失败", e); } finally { // 停止服务器(仅当按Enter时执行) server.stop(); } } }
3. 优化WebSocketEndpoint处理流式数据
针对流式传输场景,调整端点类以支持大数据量处理,并添加业务逻辑(如数据存储):
package com.tradeinsider; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; import java.io.IOException; @ServerEndpoint("/ws") public class WebSocketEndpoint { @OnOpen public void onOpen(Session session) { System.out.println("客户端连接成功:" + session.getId()); } // 处理大文本流式数据,设置最大消息大小为1MB @OnMessage(maxMessageSize = 1024 * 1024) public void onTextMessage(String message, Session session) { // 此处添加数据处理逻辑:解析JSON、存储到MySQL、计算分析等 System.out.println("收到流式数据,长度:" + message.length()); // 可选:回复客户端确认接收 // try { // session.getBasicRemote().sendText("数据已接收"); // } catch (IOException e) { // e.printStackTrace(); // } } // 可选:处理二进制流式数据 @OnMessage public void onBinaryMessage(byte[] data, Session session) { System.out.println("收到二进制流式数据,长度:" + data.length); // 二进制数据处理逻辑 } @OnClose public void onClose(Session session, CloseReason closeReason) { System.out.println("客户端断开连接:" + session.getId() + ",原因:" + closeReason.getReasonPhrase()); } @OnError public void onError(Session session, Throwable throwable) { System.err.println("客户端连接出错:" + session.getId()); throwable.printStackTrace(); } }
4. 7*24小时运行与远程Java GUI访问
- 7*24小时运行:
将项目打包成可执行jar,通过后台服务运行:- Linux:使用systemd创建服务,配置自动重启
- Windows:注册为Windows服务,设置开机自启
- 远程Java GUI访问:
- 方案1:在服务器中添加Jakarta REST接口,GUI通过HTTP请求获取收集到的数据
- 方案2:新增一个WebSocket端点,GUI连接后实时获取数据
- 方案3:直接让GUI访问存储数据的MySQL数据库,读取已收集的信息
内容的提问来源于stack exchange,提问作者Nomad
相关产品推荐
相关产品推荐

