Tomcat WebSocket Servlet 监听端口

3
我正在尝试编写一个使用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
@jalynn2,实际上我需要每个客户端到服务器的两个连接(安全和非安全)。这些连接必须由一个servlet提供服务。因此,我想我需要为此使用不同的端口(例如8443和8444)。客户端使用C++实现,使用libwebsockets库,该库允许指定要连接的服务器端口。我认为答案在server.xmlConnector元素中,但我在网络上找不到任何有用的信息。 - maverik
你是在实际运行Tomcat下,还是在使用Tomcat类编写自己的服务器? - Christopher Schultz
@ChristopherSchultz,我正在Tomcat下运行servlet。 - maverik
1
如果您正在Tomcat下运行,您可以简单地连接到Tomcat的现有HTTP连接器(默认端口为8080)。Websocket通过HTTP启动连接,然后请求“升级”,客户端和服务器之间进行持久连接的协商。您不必自己进行套接字绑定。尝试阅读非常简短的文档,其中包含指向更多信息的指针 - 包括工作代码。 - Christopher Schultz
1个回答

4

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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接