tomcat websocket servlet监听端口

Posted

技术标签:

【中文标题】tomcat websocket servlet监听端口【英文标题】:tomcat websocket servlet listening port 【发布时间】:2013-07-24 14:23:35 【问题描述】:

我正在尝试编写一个使用org.apache.catalina.websocket.WebSocketServlet 的servlet。我找到了一个 websocket 聊天的例子,但我不知道如何为 websocket 服务器指定监听端口(在这个 servlet 中实现)?例如,我需要在端口11337 上监听客户端连接。但是我该如何表达呢?

好的,这是(简化的)代码:

public class TestServlet extends WebSocketServlet 
    private static final Logger logger = LoggerFactory.getLogger(TestServlet.class);

    public TestServlet() 
        logger.error("Initializing TestServlet");
    

    @Override
    protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request) 
        logger.error("New WS connection, subProtocol=" + subProtocol + ", request=" + request.getRequestURL());
        return new TestConnection();
    

    private class TestConnection extends MessageInbound 

        @Override
        protected void onBinaryMessage(ByteBuffer byteBuffer) throws IOException 
            logger.error("onBinaryMessage");
        

        @Override
        protected void onTextMessage(CharBuffer charBuffer) throws IOException 
            logger.error("onBinaryMessage: " + charBuffer);
            sendMessage("Test message");
        

        public void sendMessage(String message) 
            WsOutbound outbound = this.getWsOutbound();
            CharBuffer cb = CharBuffer.wrap(message);
            try 
                outbound.writeTextMessage(cb);
             catch (IOException e) 
                logger.error("failed to write outbound");
            
        
    

我找不到设置监听端口的位置和方式。官方websocket 文档也没有多大帮助。

所以我猜它可以在servlet设置中的某个地方设置,但找不到。

有人有什么想法吗?

【问题讨论】:

根据 RFC6455,您需要从客户端发出 HTTP 请求以“打开”套接字。未使用端口号。 @jalynn2,实际上我需要从每个客户端到服务器的两个连接(安全和非安全)。这些连接必须由一个 servlet 提供服务。所以我想我需要单独的端口(例如 8443 和 8444)。客户端在 C++ 中使用libwebsockets 库实现,该库允许指定要连接的服务器端口。我认为答案在server.xmlConnector 元素中的某个地方,但我在网上找不到任何有用的东西。 您实际上是在 Tomcat 下运行,还是在使用 Tomcat 的类编写自己的服务器? @ChristopherSchultz,我在 Tomcat 下运行 servlet 如果您在Tomcat下运行,您可以简单地连接到Tomcat现有的HTTP连接器(默认为8080端口)。 Websocket 通过 HTTP 启动连接,然后请求“升级”,然后在客户端和服务器之间协商以实现持久连接。您不必自己进行任何套接字绑定。尝试阅读very brief documentation, which has pointers to where you can read more——包括工作代码。 【参考方案1】:

WebSocket 旨在通过 HTTP 协议工作,因此它不会像普通 TCP Socket 那样具有不同的侦听端口,但它使用与部署相同的服务器端口。

所以在您的情况下,如果您使用的是 tomcat 服务器,那么 websocket 可能会使用端口 8080(如果您没有明确修改)进行通信。您可能需要覆盖 MessageInbound 类的 onOpen 和 onClose 方法,以便在连接建立和连接关闭时获得通知。有关详细信息,请参阅下面的示例代码。

public class IncomingMessageHandler extends MessageInbound 

    private WsOutbound myoutbound;
    public IncomingMessageHandler() 

    

    @Override
    public void onOpen(WsOutbound outbound) 
        logger.info("Open Client.");
        this.myoutbound = outbound;
    

    @Override
    public void onClose(int status) 
        logger.info("Close Client.");           
    

    /**
     * Called when received plain Text Message
     */
    @Override
    public void onTextMessage(CharBuffer cb) throws IOException 

    

    /**
     * We can use this method to pass image binary data, eventually !
     */
    @Override
    public void onBinaryMessage(ByteBuffer bb) throws IOException 

    

    public synchronized void sendTextMessage(String message) 
        try 
            CharBuffer buffer = CharBuffer.wrap(message);
            this.getMyoutbound().writeTextMessage(buffer);
            this.getMyoutbound().flush();

         catch (IOException e)    
        
    

    /**
     * Set timeout in milliseconds, -1 means never
     */
    @Override
    public int getReadTimeout() 
        return -1;
    

    public WsOutbound getMyoutbound() 
        return myoutbound;
    
    public void setMyoutbound(WsOutbound myoutbound) 
        this.myoutbound = myoutbound;
    

【讨论】:

以上是关于tomcat websocket servlet监听端口的主要内容,如果未能解决你的问题,请参考以下文章

通过 Tomcat servlet 代理常规 HTTP 和 WebSocket

springboot深入学习-----tomcat配置websocket

使用 Gretty Gradle 插件测试 WebSocket

Tomcat:响应 http POST 请求的 Websocket 广播

与 Servlet 相比,使用 Websocket 下载文件速度较慢

tomcat源码springboot搭建的跑包含websocket的项目