如何构建一个websocket HttpHandler

时间:2014-09-27 20:40:39

标签: java websocket

我想在HttpServer上使用websockets。这是我想出的HttpHandler ......以及相应的EchoServer

public class WebSocketHandler implements HttpHandler {

    @Override
    public void handle(final HttpExchange exchange) throws IOException {
        String requestMethod = exchange.getRequestMethod();
        if (requestMethod.equalsIgnoreCase("GET")) {
            System.out.println("Well formed websocket Upgrade request");
            /*
             * HTTP/1.1 101 Switching Protocols
             * Upgrade: websocket
             * Connection: Upgrade
             * Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
             * ''Sec-WebSocket-Protocol: chat
             */

            Headers responseHeaders = exchange.getResponseHeaders();
            responseHeaders.set("Upgrade", "websocket");
            responseHeaders.set("Connection", "Upgrade");
            responseHeaders.set("Sec-WebSocket-Accept", "XXXX");
            exchange.sendResponseHeaders(101, 0);
            exchange.getResponseBody().write("ok".getBytes());
            ServerEndpointConfig.Builder.create(EchoServer.class, "/echo").build();
        } else {
            System.out.println("Server: non-GET websocket upgrade request....");
            exchange.sendResponseHeaders(200, 0);
            exchange.getResponseBody().write("ok".getBytes());
        }

    }
}

EchoServer类是:

@ServerEndpoint(value = "/echo")
public class EchoServer {

    private Logger logger = Logger.getLogger(this.getClass().getName());
    int id = 0;

    @OnOpen
    public void onOpen(Session session) {
        logger.info("Connected ... " + session.getId());
    }

    @OnMessage
    public String onMessage(String message, Session session) {
        switch (message) {
            case "quit":
                try {
                    session.close(new CloseReason(CloseCodes.NORMAL_CLOSURE, "Game ended"));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                break;
        }
        id++;
        return String.format("%d:%s", id, message);
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
    }
}

我没有太多希望这会起作用,因为我认为连接ID不会被交换。

如何完成此代码以获得功能性websocket连接?

1 个答案:

答案 0 :(得分:1)

使用com.sun.net.httpserver.HttpExchange进行WebSocket无法正常工作。

该API的API不允许真正的升级连接。换句话说,没有HTTP连接编码或封装的连接(例如chunked或gziped等)

此外,您对WebSocket升级的协议处理不是有效的,没有浏览器会发现该响应有效并继续升级。

代码中的2个示例。

    必须提供
  • Sec-WebSocket-Accept,并根据传入的请求标头正确计算
  • 如果传入的请求有一个已定义的,则必须提供
  • Sec-WebSocket-Protocol