Cometd WebSocket连接报错:Unknown Bayeux Transport 求助
结合你的依赖配置、日志信息和问题描述,核心问题是Cometd服务器无法识别WebSocket类型的Bayeux传输,我整理了几个关键的排查和解决步骤:
1. 补充Cometd WebSocket服务器依赖
你的pom.xml仅引入了cometd-java-server,但Cometd的WebSocket传输实现封装在独立的cometd-java-websocket-server包中——没有这个依赖,服务器根本不知道如何处理WebSocket类型的Bayeux请求。
在dependencies节点中添加以下依赖:
<dependency> <groupId>org.cometd.java</groupId> <artifactId>cometd-java-websocket-server</artifactId> <version>${cometd.version}</version> </dependency>
这个依赖会自动引入Cometd与Jetty WebSocket交互的适配类,让服务器能够识别WebSocket传输协议。
2. 修正客户端WebSocket连接地址
你当前使用的连接地址http://localhost:8080/cometd/test混淆了Cometd端点路径和Bayeux通道路径:
- Cometd的WebSocket连接地址应指向CometDServlet的映射路径(比如
ws://localhost:8080/cometd) /test是你要订阅/发布的Bayeux通道,这个路径是在连接成功后通过Bayeux消息指定的,不属于WebSocket连接URL的一部分
即使你的CometDServlet映射是/cometd/*,/cometd/test能匹配到Servlet,但Cometd的WebSocket传输期望的是根端点路径,所以调整客户端连接URL为ws://localhost:8080/cometd再试。
3. 调整Jetty WebSocket过滤器行为
从日志可以看到Jetty_WebSocketUpgradeFilter在CometDServlet之前被调用,但Cometd的WebSocket是基于Bayeux协议的自定义实现,并非标准JSR-356 WebSocket端点,Jetty的默认过滤器会拦截WebSocket升级请求,导致Cometd无法处理。
你可以通过以下两种方式解决:
方式一:禁用Jetty自动WebSocketUpgradeFilter
如果是代码配置Jetty,添加如下设置:
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); // 禁用Jetty自动创建的WebSocketUpgradeFilter context.getServletContext().setAttribute("org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter", Boolean.FALSE);
如果是web.xml配置,添加:
<context-param> <param-name>org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter</param-name> <param-value>false</param-value> </context-param>
方式二:显式配置Cometd传输类
在CometDServlet的初始化参数中,显式指定WebSocket传输类,确保服务器能加载到:
ServletHolder cometdHolder = new ServletHolder(new CometDServlet()); // 显式注册WebSocket和长轮询传输 cometdHolder.setInitParameter("transports", "org.cometd.websocket.server.WebSocketTransport," + "org.cometd.server.transport.LongPollingTransport"); // 按需添加其他参数,比如允许跨域 cometdHolder.setInitParameter("allowedOrigins", "*"); context.addServlet(cometdHolder, "/cometd/*");
4. 验证版本兼容性
你的Jetty版本9.2.22与Cometd 3.1.3是兼容的,添加cometd-java-websocket-server后,Maven会自动管理依赖版本,无需额外调整。
按以上步骤调整后,重启服务器和客户端,应该就能正常建立WebSocket连接了。
内容的提问来源于stack exchange,提问作者Magnus Lutz

