在这些日子里,我尝试使用Jetty实现WebSocket服务器。
我创建了一个名为" WebSocketServer"的Jetty项目。在demo-base
的分布中为Jetty 9.2.0.v20140526
。
之后,我编写了一些代码来实现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 :(得分: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的虚拟实例。有许多选项可以强制加载包,但它们与此问题无关。