基于Tomcat的WebSocket(5月8日更新)

langqiao 2013-06-27

之前大概的看过WebSocket,当时Tomcat还不支持WebSocket,所以当时写了一篇基于Jetty的WebSocket实现,地址如下:

现在Tomcat7.0.27发布了,从这个版本开始Tomcat就支持WebSocket了。

Tomcat的WebSocket和Jetty的大致上差不多,大同小异,这里就简单的贴两个类吧(此例子未考虑多线程的情况):

第一个类,这个和Jetty一样,需要一个Servlet来处理WebSocket请求:

package lhc.websocket;  
  
import org.apache.catalina.websocket.StreamInbound;  
import org.apache.catalina.websocket.WebSocketServlet;  
  
public class MyWebSocketServlet extends WebSocketServlet {  
  
    private static final long serialVersionUID = -7178893327801338294L;  
  
    @Override  
    protected StreamInbound createWebSocketInbound(String arg0) {  
System.out.println("##########");  
        return new MyMessageInbound();  
    }  
  
}  

这个Servlet继承自WebSocketServlet,实现createWebSocketInbound方法。该方法返回第二个类的实例。

第二个类,处理每一次具体的WebSocket任务:

package lhc.websocket;  
  
import java.io.IOException;  
import java.nio.ByteBuffer;  
import java.nio.CharBuffer;  
  
import lhc.init.InitServlet;  
  
import org.apache.catalina.websocket.MessageInbound;  
import org.apache.catalina.websocket.WsOutbound;  
  
public class MyMessageInbound extends MessageInbound {  
  
    @Override  
    protected void onBinaryMessage(ByteBuffer arg0) throws IOException {  
        // TODO Auto-generated method stub  
          
    }  
  
    @Override  
    protected void onTextMessage(CharBuffer msg) throws IOException {  
        for (MessageInbound messageInbound : InitServlet.getSocketList()) {  
            CharBuffer buffer = CharBuffer.wrap(msg);  
            WsOutbound outbound = messageInbound.getWsOutbound();  
            outbound.writeTextMessage(buffer);  
            outbound.flush();  
        }  
          
    }  
  
    @Override  
    protected void onClose(int status) {  
        InitServlet.getSocketList().remove(this);  
        super.onClose(status);  
    }  
  
    @Override  
    protected void onOpen(WsOutbound outbound) {  
        super.onOpen(outbound);  
        InitServlet.getSocketList().add(this);  
    }  
      
      
  
}  

 这个类继承自MessageInbound类,必须实现onBinaryMessage和onTextMessage方法。Jetty中只有一个onMessage方法,而Tomcat细化成了2个方法。

还要一个初始化的Servlet

package lhc.init;  
  
import java.util.ArrayList;  
import java.util.List;  
  
import javax.servlet.ServletConfig;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
  
import org.apache.catalina.websocket.MessageInbound;  
  
public class InitServlet extends HttpServlet {  
  
    private static final long serialVersionUID = -3163557381361759907L;  
      
    private static List<MessageInbound> socketList;    
      
    public void init(ServletConfig config) throws ServletException {    
        InitServlet.socketList = new ArrayList<MessageInbound>();    
        super.init(config);    
        System.out.println("Server start============");    
    }    
        
    public static List<MessageInbound> getSocketList() {    
        return InitServlet.socketList;    
    }    
}  

最后,web.xml中进行一下Servlet的配置。

Xml代码  基于Tomcat的WebSocket(5月8日更新)
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  3.   <display-name>wsoc</display-name>  
  4.   <welcome-file-list>  
  5.     <welcome-file>index.jsp</welcome-file>  
  6.   </welcome-file-list>  
  7.     
  8.   <servlet>  
  9.     <servlet-name>mywebsocket</servlet-name>  
  10.     <servlet-class>lhc.websocket.MyWebSocketServlet</servlet-class>  
  11.   </servlet>  
  12.   <servlet-mapping>  
  13.     <servlet-name>mywebsocket</servlet-name>  
  14.     <url-pattern>*.do</url-pattern>  
  15.   </servlet-mapping>  
  16.     
  17.   <servlet>  
  18.     <servlet-name>initServlet</servlet-name>  
  19.     <servlet-class>lhc.init.InitServlet</servlet-class>  
  20.     <load-on-startup>1</load-on-startup>  
  21.   </servlet>  
  22. </web-app>  

页面的话,就是标准的HTML5的websocket,这个和服务器是否是Tomcat或者Jetty是无关的:

Html代码  基于Tomcat的WebSocket(5月8日更新)
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html>  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title>Index</title>  
  8. <script type="text/javascript">  
  9. var ws = null;  
  10. function startWebSocket() {  
  11.     if ('WebSocket' in window)  
  12.         ws = new WebSocket("ws://localhost:8080/wsoc/mywebsocket.do");  
  13.     else if ('MozWebSocket' in window)  
  14.         ws = new MozWebSocket("ws://localhost:8080/wsoc/mywebsocket.do");  
  15.     else  
  16.         alert("not support");  
  17.       
  18.       
  19.     ws.onmessage = function(evt) {  
  20.         alert(evt.data);  
  21.     };  
  22.       
  23.     ws.onclose = function(evt) {  
  24.         alert("close");  
  25.     };  
  26.       
  27.     ws.onopen = function(evt) {  
  28.         alert("open");  
  29.     };  
  30. }  
  31.   
  32. function sendMsg() {  
  33.     ws.send(document.getElementById('writeMsg').value);  
  34. }  
  35. </script>  
  36. </head>  
  37. <body onload="startWebSocket();">  
  38. <input type="text" id="writeMsg"></input>  
  39. <input type="button" value="send" onclick="sendMsg()"></input>  
  40. </body>  
  41. </html> 

相关推荐