2013-07-24 288 views
3

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

OK,这里是(简化)代码:

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设置的某个地方设置,但无法找到位置。

有没有人有任何想法?

+0

根据RFC6455,您需要从客户端发出HTTP请求以“打开”套接字。没有使用端口号。 – jalynn2

+0

@ jalynn2,实际上我需要从每个客户端到服务器的两个连接(安全和非安全)。这些连接必须由一个servlet提供。所以我想我需要单独的端口(例如8443和8444)。客户端使用'libwebsockets'库以C++实现,该库允许指定服务器的端口连接。我认为答案在'server.xml'和'Connector'元素的某个地方,但我在网上找不到任何有用的东西。 – maverik

+0

你确实在Tomcat下运行,还是使用Tomcat的类编写自己的服务器? –

回答

4

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

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

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