2014-06-06 295 views
3

在這些日子裏,我嘗試通過使用Jetty來實現WebSocket服務器。Jetty - 獨立WebSocket服務器

我在Jetty 9.2.0.v20140526的發行版中創建了一個名爲「WebSocketServer」的Jetty項目demo-base

之後,我寫了一些代碼來實現WebSocket機制,並將所有代碼導出到war文件,以將其推送到「WebSocketServer」的webapps文件夾。當我java -jar ..<jetty.home>/start.jar,這是可行的。但是,在我創建了一個到這個WebSocket項目的新連接之後,發生了一些錯誤代碼。

java.lang.ClassCastException: org.eclipse.jetty.server.HttpConnection cannot be cast to org.eclipse.jetty.server.HttpConnection 
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:175) 
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:148) 
at org.eclipse.jetty.websocket.servlet.WebSocketServlet.service(WebSocketServlet.java:151) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751) 
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566) 
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578) 
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221) 
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111) 
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498) 
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183) 
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045) 
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:199) 
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109) 
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98) 
at org.eclipse.jetty.server.Server.handle(Server.java:461) 
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284) 
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244) 
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534) 
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) 
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) 
at java.lang.Thread.run(Thread.java:744) 

我不知道發生了什麼事?以下代碼是我編寫的構建簡單WebSocket服務器的代碼。

的Servlet:

@SuppressWarnings("serial") 
public class XYZWebSocketServlet extends WebSocketServlet{ 
    @Override 
    public void configure(WebSocketServletFactory factory) { 
     factory.getPolicy().setIdleTimeout(600000); 
     factory.register(XYZWebSocketEvent.class); 
    } 
} 

事件:

@WebSocket 
public class XYZWebSocketEvent { 
    private Session session; 

    @OnWebSocketConnect 
    public void onConnect(Session sess) { 
     session = sess; 

     // Get parameters while client connect to server 
     Map<String,List<String>> parameters = session.getUpgradeRequest().getParameterMap(); 
     String encyptedID = parameters.get("ID").get(0); 

     System.out.println("Connect: " + session.getRemoteAddress().getPort()); 
     try { 
      session.setIdleTimeout(600000); 
      session.getRemote().sendString("Hello!"); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 

    @OnWebSocketMessage 
    public void onMessage(String message) { 
      try { 
       session.getRemote().sendString("Message: " + message); 
      } 
      catch (Exception ex) { 
      } 
    } 

    @OnWebSocketClose 
    public void onClose(int statusCode, String reason) { 
      try { 
       session.getRemote().sendString("Close: statusCode=" + statusCode + ", reason=" +reason); 
     } 
      catch (Exception ex) { 
      } 
    } 

    @OnWebSocketError 
    public void onError(Throwable t) { 
     System.out.println("Error: " + t.getMessage()); 
    } 

    public Session getSession() { 
     return this.session; 
    } 
} 

web.xml中:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app> 
    <display-name>WebSocket application</display-name> 
    <servlet> 
     <servlet-name>XYZWebSocketServlet</servlet-name> 
     <servlet-class>com.newKinpo.servlet.XYZWebSocketServlet</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>XYZWebSocketServlet</servlet-name> 
     <url-pattern>/events/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

有什麼錯嗎?感謝您的關注。

回答

0

我有類似的問題,我找到了原因和解決方案。嵌入式Jetty服務器由SUN類加載器加載(稍後將調用它爲系統類加載器)在掃描webapp目錄後,我的應用程序由WebApp類加載器加載,當涉及到WebSocketServerFactory時,它由WebApp加載。然而,從請求中獲得的org.eclipse.jetty.server.HttpConnection對象是由系統類加載器加載的。

根據https://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading jetty websocket軟件包被視爲系統類軟件包,不應由WebApp加載(如果已由系統加載)。

解決方案是在初始化jetty服務器時強制加載包org.eclipse.jetty.websocket。

我剛剛創建了例如WebSocketHandler的虛擬實例。有很多選項可以強制包裝加載,但它們與此問題無關。

+0

你能否提供關於虛擬實例的更多細節 – Yogesh