我已经实现了一个基本的websocket服务器在Jetty(独立模式)。
MyWebSocketServlet.java
public class MyWebSocketServlet extends WebSocketServlet {
@Override
public void configure(WebSocketServletFactory webSocketServletFactory){
webSocketServletFactory.getPolicy().setIdleTimeout(1000 * 10 * 60);
webSocketServletFactory.setCreator(new MyWebSocketFactory());
}
}
MyWebSocketFactory.java
public class MyWebSocketFactory implements WebSocketCreator {
public Object createWebSocket(
ServletUpgradeRequest servletUpgradeRequest
, ServletUpgradeResponse servletUpgradeResponse) {
return new MyWebSocketListener();
}
}
MyWebSocketListener.java
public class MyWebSocketListener implements WebSocketListener {
private Session sessionInstance;
public void onWebSocketBinary(byte[] bytes, int i, int i1) {
ByteBuffer data = ByteBuffer.wrap(bytes, i, i1);
try {
sessionInstance.getRemote().sendBytes(data);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onWebSocketClose(int i, String s) {
}
public void onWebSocketConnect(Session session) {
sessionInstance = session;
}
public void onWebSocketError(Throwable throwable) {
throwable.printStackTrace(System.err);
}
public void onWebSocketText(String s) {
try {
sessionInstance.getRemote().sendString(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
web . xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="false"
version="3.1">
<servlet>
<servlet-name>WsEcho</servlet-name>
<servlet-class>org.test.sanket.MyWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WsEcho</servlet-name>
<url-pattern>/echo/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HttpEcho</servlet-name>
<servlet-class>org.test.sanket.MyHttpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpEcho</servlet-name>
<url-pattern>/httpecho/*</url-pattern>
</servlet-mapping>
</web-app>
如果我使用嵌入式Jetty并以编程方式配置服务器并添加servlet,那么这个示例运行得很好,而不是使用独立Jetty。但是,如果我打包相同的战争,然后在独立的jetty实例中部署相同的,我有以下观察:
- 我能够击中HttpServlet,即MyHttpServlet并接收响应
- 但是当我试图击中websocket servlet,即MyWebSocketServlet,我看到以下错误:
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)
我确实看到了以下链接:Jetty -独立的WebSocket服务器
从上面的链接来看,这似乎是一个类加载问题,因为jetty websocket包被视为系统类包,如果已经被系统加载,则不应该被WebApp加载。
因此,根据上面的链接,我研究了建议的细节:http://www.eclipse.org/jetty/documentation/9.2.10.v20150310/jetty-classloading.html
在这个链接中,解决这个问题的方法之一是调用org.eclipse.jetty.webapp.WebAppContext。setSystemClasses(String Array)或org.eclipse.jetty.webapp.WebAppContext.addSystemClass(String)允许对哪些类被认为是系统类进行精细控制。
为了能够做到这一点,我应该能够获得WebAppContext的一个实例,当Jetty初始化和添加WebSocket类作为系统类。
我试着寻找一个人如何能够达到同样的效果,但到目前为止没有运气?有没有人能给我指出一个参考实现,如何实现这一点?
Java Version: OpenJDK 7(latest)
Jetty: 9.2.10.v20150310
操作系统:Ubuntu 14.04
提前感谢!
如果您已经按照这个链接设置了Jetty独立实例,那么您可能已经运行了以下命令:
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging
如果是这样,那么当你尝试访问websocket servlet时,你会看到你注意到的异常。
你所需要做的就是,除了这个命令,你还需要初始化websocket模块,如下所示:
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging,websocket
希望这对你有帮助!
不要在战争的WEB-INF/lib
或WEB-INF/classes
目录中包含org.eclipse.jetty.*
类