如何为Jetty websockets实例化WebSocketAdapter实例

时间:2014-04-13 21:41:28

标签: websocket jetty

我按照示例创建了一个websocket服务器:

    Server server = new Server();
    ServerConnector connector = new ServerConnector(server);
    connector.setPort(port);
    server.addConnector(connector);

    ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/", true, false);

    EventServlet es = injector.getInstance(EventServlet.class);
    servletContextHandler.addServlet(new ServletHolder(es), "/events/*");

EventServlet类如下所示:

    public class EventServlet extends WebSocketServlet {
        @Override
        public void configure(WebSocketServletFactory factory) {
            factory.getPolicy().setIdleTimeout(10000);
            factory.register(EventSocketCache.class);

        }
    }

EventSocketCache看起来像:

public class EventSocketCache extends WebSocketAdapter {


private static int i = 0;
private static int counter = 0;

private static Map<Integer, Session> sessionMap = new HashMap<>();

private final Cache<String, String> testCache;

@Inject
public EventSocketCache(Cache<String, String> testCache) {
    this.testCache = testCache;
}

@Override
public void onWebSocketConnect(Session session) {
    super.onWebSocketConnect(session);
    System.out.println("Socket Connected: " + session);
    System.out.println("Connect: " + session.getRemoteAddress().getAddress());
    try {
        session.getRemote().sendString("Hello Webbrowser");
        session.setIdleTimeout(50000);        
    } catch (IOException e) {
        e.printStackTrace();
    }
}


@Override
public void onWebSocketText(String message) {
    super.onWebSocketText(message);
    System.out.println("Received TEXT message: " + message);
}


@Override
public void onWebSocketBinary(byte[] payload, int offset, int len) {
    byte[] newData = Arrays.copyOfRange(payload, offset, offset + len);

    try {
        Common.Success success = Common.Success.parseFrom(newData);
        System.err.println("------> " + success.getIsSuccess());
    } catch (InvalidProtocolBufferException e) {
        e.printStackTrace();
    }
}


@Override
public void onWebSocketClose(int statusCode, String reason) {
    System.err.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    // Remove from the list here....
    super.onWebSocketClose(statusCode, reason);
    System.out.println("Socket Closed: [" + statusCode + "] " + reason);
}


@Override
public void onWebSocketError(Throwable cause) {
    System.err.println("######################################");
    super.onWebSocketError(cause);
    cause.printStackTrace(System.err);
}

}

现在,当我使用我的客户端并发送请求时,我最终得到了:

org.eclipse.jetty.websocket.api.UpgradeException: Didn't switch protocols
at org.eclipse.jetty.websocket.client.io.UpgradeConnection.validateResponse(UpgradeConnection.java:249)
at org.eclipse.jetty.websocket.client.io.UpgradeConnection.read(UpgradeConnection.java:181)
at org.eclipse.jetty.websocket.client.io.UpgradeConnection.onFillable(UpgradeConnection.java:126)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527)
at java.lang.Thread.run(Thread.java:722)
Disconnected from the target VM, address: '127.0.0.1:63256', transport: 'socket'
java.util.concurrent.ExecutionException: org.eclipse.jetty.websocket.api.UpgradeException: Didn't switch protocols
    at org.eclipse.jetty.util.FuturePromise.get(FuturePromise.java:123)
    at com.gamecenter.websockets.EventClient.main(EventClient.java:25)
Caused by: org.eclipse.jetty.websocket.api.UpgradeException: Didn't switch protocols
    at org.eclipse.jetty.websocket.client.io.UpgradeConnection.validateResponse(UpgradeConnection.java:249)
    at org.eclipse.jetty.websocket.client.io.UpgradeConnection.read(UpgradeConnection.java:181)
    at org.eclipse.jetty.websocket.client.io.UpgradeConnection.onFillable(UpgradeConnection.java:126)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527)
    at java.lang.Thread.run(Thread.java:722)

似乎创建EventSocketCache实例时出现问题;如果我没有那里的构造函数,一切正常。 我想知道如何正确实例化EventSocketCache并将其注册到EventServlet以便它可以工作吗?

1 个答案:

答案 0 :(得分:1)

我想我已经为您的问题找到了解决方案。您必须在WebSocketServlet中使用WebSocketCreator:

public class MenuServlet extends WebSocketServlet {
@Inject
private Injector injector;

@Override
public void configure(WebSocketServletFactory webSocketServletFactory) {
    // Register your Adapater
    webSocketServletFactory.register(MenuSocket.class);

    // Get the current creator (for reuse)
    final WebSocketCreator creator = webSocketServletFactory.getCreator();

    // Set your custom Creator
    webSocketServletFactory.setCreator(new WebSocketCreator() {
        @Override
        public Object createWebSocket(ServletUpgradeRequest servletUpgradeRequest, ServletUpgradeResponse servletUpgradeResponse) {
            Object webSocket = creator.createWebSocket(servletUpgradeRequest, servletUpgradeResponse);

            // Use the object created by the default creator and inject your members
            injector.injectMembers(webSocket);

            return webSocket;
        }
    });
  }
}

您可以将您的成员注入WebSocketAdapater。这实际上对我有用。