You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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方法
WsOutboundSession.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:53:11