You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

编程实例化Tomcat 7时Javax WebSockets无法正常工作

解决Tomcat7纯代码搭建下的WebSocket端点配置问题

我之前也碰到过纯代码启动Tomcat时WebSocket端点死活注册不上的情况,核心原因是Tomcat默认不会自动启用WebSocket的初始化器——尤其是你这种完全不碰配置文件的场景。给你几个关键步骤来解决:

先确认依赖是否正确

Tomcat7的WebSocket支持需要两个核心包,版本要和你的Tomcat7版本严格匹配(比如用7.0.109):

  • tomcat-websocket-api:对应Javax WebSocket 1.1的API定义
  • tomcat-websocket:Tomcat的WebSocket底层实现

如果用Maven,依赖可以这么加:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-websocket-api</artifactId>
    <version>7.0.109</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-websocket</artifactId>
    <version>7.0.109</version>
    <scope>provided</scope>
</dependency>

手动注册WebSocket初始化器

纯代码创建的Context不会自动扫描WebSocket的ServletContainerInitializer,所以必须手动把Tomcat的WsSci注册进去。在你配置Context的代码段里添加这一行:

import org.apache.tomcat.websocket.server.WsSci;

// ... 你的Tomcat初始化代码 ...
Context context = new StandardContext();
// 先设置Context的docBase、路径等常规属性

// 关键:注册WebSocket的初始化器
context.addServletContainerInitializer(new WsSci(), null);

注册WebSocket端点的两种方式

方式1:用@ServerEndpoint注解

如果你的端点类已经用了注解(比如@ServerEndpoint("/ws/echo")),现在WsSci会自动扫描并注册这些端点,只要你的类在Tomcat的类路径下就行。示例端点类:

import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/ws/echo")
public class EchoWebSocket {
    @OnMessage
    public String echo(String message) {
        return "Received: " + message;
    }
}

方式2:编程式动态注册

如果不想用注解,或者需要动态配置端点,可以通过ServerContainer手动添加:

import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;

// 在Context初始化完成后获取ServerContainer
ServerContainer serverContainer = (ServerContainer) context.getServletContext().getAttribute(ServerContainer.class.getName());

// 构建端点配置并注册
ServerEndpointConfig config = ServerEndpointConfig.Builder.create(EchoWebSocket.class, "/ws/echo").build();
serverContainer.addEndpoint(config);

验证小技巧

启动Tomcat后,先看日志里有没有WsSci加载的相关信息;然后用浏览器控制台测试连接:

let ws = new WebSocket('ws://localhost:8080/ws/echo');
ws.onmessage = (event) => console.log(event.data);
ws.send('Hello WebSocket!');

如果能收到返回的消息,就说明配置成功了。

内容的提问来源于stack exchange,提问作者Yuval Herziger

火山引擎 最新活动