如何将guacamole-client中tomcat依赖从7升级到8+并解决WebSocket迁移问题?
迁移Guacamole WebSocket隧道到Tomcat 8+/9的JSR356标准API
核心背景
Tomcat 8开始弃用org.apache.catalina.websocket下的自定义API,全面转向JSR356(WebSocket 1.1)标准API,你遇到的类无法解析问题正是因为旧API被移除。以下是具体迁移步骤:
1. 调整依赖
移除对tomcat-catalina和tomcat-coyote中旧WebSocket类的依赖,改用标准WebSocket API:
- 若基于Java EE:引入
javax.websocket-api(版本1.1+),并设置为provided(Tomcat 9自带该API的实现) - 若基于Jakarta EE:引入
jakarta.websocket-api(版本2.0+),同样设置为provided
2. 重构GuacamoleWebSocketTunnelServlet
原来继承WebSocketServlet的方式要替换为JSR356的注解式或编程式实现:
示例:注解式实现(推荐)
import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/guacamole/websocket-tunnel") public class GuacamoleWebSocketTunnelEndpoint { @OnOpen public void onOpen(Session session) { // 替代原createWebSocketInbound的初始化逻辑,比如创建隧道连接 // 可以将Session与Guacamole的Tunnel关联 } @OnMessage public void onMessage(String message, Session session) { // 处理客户端发送的消息,替代原StreamInbound.onTextMessage // 解析Guacamole指令,调用Tunnel相关逻辑 } @OnMessage public void onBinaryMessage(byte[] bytes, Session session) { // 处理二进制消息(如果需要),替代原StreamInbound.onBinaryMessage } @OnClose public void onClose(Session session) { // 清理资源,关闭隧道连接,替代原StreamInbound.onClose } @OnError public void onError(Session session, Throwable throwable) { // 处理异常,替代原StreamInbound.onError } // 发送数据到客户端:使用session.getBasicRemote().sendText()或sendBinary() // 替代原WsOutbound的writeTextMessage/writeBinaryMessage }
关键映射关系
| 旧Tomcat WebSocket类/方法 | JSR356对应实现 |
|---|---|
WebSocketServlet | @ServerEndpoint注解类 |
StreamInbound | @OnOpen/@OnMessage/@OnClose方法 |
WsOutbound | Session.getBasicRemote()/getAsyncRemote() |
createWebSocketInbound() | @OnOpen中初始化隧道逻辑 |
3. 适配Guacamole隧道逻辑
Guacamole的核心隧道逻辑(Tunnel、GuacamoleReader/GuacamoleWriter)无需修改,但需要调整数据读写的适配层:
- 从客户端接收的消息:在
@OnMessage中解析为Guacamole指令,传入Tunnel的acquireReader()处理 - 向客户端发送数据:通过
Session的远程发送方法,将Tunnel的acquireWriter()输出的内容转发
4. 部署注意事项
- Tomcat 9自带JSR356实现,无需额外引入
tomcat-websocket.jar等依赖,避免版本冲突 - 确保项目的WebSocket API依赖范围为
provided,防止打包时带入API jar导致冲突
官方参考资源
- Tomcat官方迁移文档:明确提到旧WebSocket API已废弃,建议迁移至JSR356,可查看Tomcat 8/9官方文档中"WebSocket"章节的迁移说明
- Guacamole官方代码:查看Guacamole 1.4.0及以上版本的
WebSocketTunnelServlet实现,已完全适配JSR356,可直接参考其源码逻辑
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

