Jetty - stand alone WebSocket server

隐身守侯 提交于 2019-12-09 01:16:52

问题


in these days I try to implement a WebSocket server by using Jetty.

I've created a Jetty project called "WebSocketServer" as demo-base in the distribution of Jetty 9.2.0.v20140526.

After that, I write some codes to implement the WebSocket mechanism and export all codes to a war file to push it to the webapps folder of "WebSocketServer". When I java -jar ..<jetty.home>/start.jar, it is all workable. But, after I create a new connection to this WebSocket project, there are some error codes happened.

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)

I have no idea what's going on? The following codes are what I write to build a simple WebSocket server.

Servlet:

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

Event:

@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>

Is there something wrong? Thanks for your attention.


回答1:


I had similiar problem and I have found the cause and the solution. Embeded jetty server is loaded by SUN class loader (will call it system class loader later) after webapp directory is scanned my app is loaded by WebApp class loader and when it comes to WebSocketServerFactory it is loaded by WebApp. However org.eclipse.jetty.server.HttpConnection object obtained from the request is loaded by the system class loader.

According to https://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading jetty websocket package is treated as system class package and shouldn't be loaded by the WebApp if already loaded by the system.

The solution is to force loading of the package org.eclipse.jetty.websocket at the time jetty server is initialized.

I just create dummy instance of WebSocketHandler for example. There are many options to force package loading but they are irrelevant to this question.



来源:https://stackoverflow.com/questions/24073538/jetty-stand-alone-websocket-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!