Jetty-独立WebSocket服务器

Jetty-独立WebSocket服务器,websocket,jetty-9,Websocket,Jetty 9,最近我尝试使用Jetty实现WebSocket服务器 我在Jetty 9.2.0.v20140526的发行版中创建了一个名为“WebSocketServer”的Jetty项目,作为demo base 之后,我编写了一些代码来实现WebSocket机制,并将所有代码导出到war文件中,将其推送到“WebSocketServer”的webapps文件夹中。当我java-jar../start.jar时,一切都是可行的。但是,在我创建到这个WebSocket项目的新连接之后,出现了一些错误代码 jav

最近我尝试使用Jetty实现WebSocket服务器

我在Jetty 9.2.0.v20140526的发行版中创建了一个名为“WebSocketServer”的Jetty项目,作为
demo base

之后,我编写了一些代码来实现WebSocket机制,并将所有代码导出到
war
文件中,将其推送到“WebSocketServer”的
webapps
文件夹中。当我
java-jar../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;
    }
}
<?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>
事件:

@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;
    }
}
<?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>
@WebSocket
公共类XYZWebSocketEvent{
非公开会议;
@OnWebSocketConnect
公共连接无效(会话sess){
会话=sess;
//在客户端连接到服务器时获取参数
映射参数=session.getUpgradeRequest().getParameterMap();
字符串encyptedID=parameters.get(“ID”).get(0);
System.out.println(“连接:+session.getRemoteAddress().getPort());
试一试{
session.setIdleTimeout(600000);
session.getRemote().sendString(“Hello!”);
}捕获(ioe异常ioe){
ioe.printStackTrace();
}
}
@OnWebSocketMessage
公共消息无效(字符串消息){
试试{
session.getRemote().sendString(“Message:+Message”);
}
捕获(例外情况除外){
}
}
@OnWebSocketClose
public void onClose(int statusCode,字符串原因){
试一试{
session.getRemote().sendString(“关闭:statusCode=“+statusCode+”,reason=“+reason”);
}
捕获(例外情况除外){
}
}
@OnWebSocketError
公共作废登记员(可丢弃的t){
System.out.println(“错误:+t.getMessage());
}
公共会话getSession(){
返回此会话;
}
}
web.xml:

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

WebSocket应用程序
XYZWebSocketServlet
com.newKinpo.servlet.XYZWebSocketServlet
XYZWebSocketServlet
/事件/*

有什么不对劲吗?谢谢您的关注。

我遇到了类似的问题,我已经找到了原因和解决方案。嵌入式jetty服务器由SUN类加载器加载(稍后将称之为系统类加载器),在扫描webapp目录后,我的应用由webapp类加载器加载,当涉及WebSocketServerFactory时,由webapp加载。但是,从请求中获得的org.eclipse.jetty.server.HttpConnection对象由系统类加载器加载

根据jetty,websocket包被视为系统类包,如果系统已经加载,则不应由WebApp加载

解决方案是在jetty服务器初始化时强制加载包org.eclipse.jetty.websocket


例如,我只是创建WebSocketHandler的虚拟实例。强制加载包的选项有很多,但它们与此问题无关。

能否提供有关虚拟实例的更多详细信息