Tomcat和Jetty對WebSocket的支持
Tomcat:
J2EE下面用的最多的容器應該就是tomcat了。說到tomcat對WebSocket的支持,不得不先提一下,目前的WebSocket協議已經經過了好幾代的演變,不同瀏覽器對此協議的支持程度也不同,因此,如果作為服務器,最理想的是支持盡可能多的WebSocket協議版本。
tomcat8真正支持jsr-356(包含對websocket的支持), tomcat7支持部分版本的websocket實現不兼容jsr-356。因此,能用tomcat8的話,還是盡量用。
代碼實現相當簡單,以下是一個列子,只需要tomcat8的基本庫,不需要其他依賴。
Jetty:
Jetty和Tomcat一樣,也是一個Servlet的容器。如果說不同之處,那么最大的不同應該是Tomcat采用的是BIO處理方式,也就是說一個request會用一個線程去處理,即使是WebSocket這種長連接,也是會獨立開一個線程。作為一個普通的Web服務器,tomcat可以輕松應對耗時比較短的Request/Response。但是如果換成是長連接的WebSocket,那麻煩就來了,對于上萬用戶的聊天和推送,總不能開上萬個線程去處理吧。此時,Jetty的性能就體現出來了,Jetty采用的是NIO,一個線程可以處理多個WebSocket的長鏈接,如果你的需求是大量耗時比較長的request或者大量長連接,那么建議采用Jetty。
Jetty對WebSocket的實現有點繞,Servlet不再是繼承原來的HttpServlet,而是繼承WebSocketServlet。此處要注意導入jetty-util.jar和jetty-websocket.jar兩個包,否則可能會有class not found錯誤。
ReverseAjaxServlet.java:
Endpoints.java:
Endpoint.java
import java.io.IOException;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.codehaus.jettison.json.JSONArray;
import org.eclipse.jetty.websocket.WebSocket;
/**
* @author Mathieu Carbou (mathieu.carbou@gmail.com)
*/
class Endpoint implements WebSocket.OnTextMessage {
protected Connection _connection;
private Endpoints endpoints;
private static int clientCounter = 0;
private int clientId = clientCounter++;
public Endpoint(Endpoints endpoints) {
this.setEndpoints(endpoints);
}
@Override
public void onClose(int code, String message) {
System.out.println("Client disconnected");
this.endpoints.remove(this);
}
@Override
public void onOpen(Connection connection) {
System.out.println("Client connected");
_connection = connection;
try {
this._connection.sendMessage(new JSONArray().put("ClientID = " + clientId).toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
endpoints.offer(this);
}
@Override
public void onMessage(final String data) {
System.out.println("Received data: " + data);
this.endpoints.broadcast(data);
}
public Endpoints getEndpoints() {
return endpoints;
}
public void setEndpoints(Endpoints endpoints) {
this.endpoints = endpoints;
}
}
輔助工具:
在編寫服務器最麻煩的是要寫對應的客戶端來測試,還好Chrome為我們解決了這個問題。下載Chrome插件WebSocket Clinet可以輕松地和服務器建立連接,發送消息到服務器。
來自:http://blog.csdn.net/lrenjun/article/details/39934823