【发布时间】:2015-11-18 21:54:44
【问题描述】:
我已经在 Jetty(独立模式)中实现了一个基本的 websocket 服务器。
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>
如果我使用嵌入式码头并以编程方式配置服务器并添加 Servlet,而不是使用独立码头,那么此示例运行良好。
但是,如果我将其打包为一场战争,然后将其部署在一个独立的码头实例中,我会得到以下观察结果:
- 我可以点击 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 - stand alone WebSocket server
从上面的链接来看,这似乎是一个类加载问题,因为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)允许精细控制哪些类被视为系统类。
因此,为了能够做到这一点,我应该能够在 Jetty 初始化并将 WebSocket 类添加为系统类时获取 WebAppContext 的实例。
我试图寻找一个人如何能够实现相同但到目前为止没有运气?任何人都可以向我指出如何实现这一点的参考实现吗?
Java 版本:OpenJDK 7(最新)
码头:9.2.10.v20150310
操作系统:Ubuntu 14.04
提前致谢!
【问题讨论】: