如何构建一个 websocket HttpHandler [英] How to build a websocket HttpHandler
问题描述
我想在 HttpServer 上使用 websockets.这是我想出的 HttpHandler ... 和相应的 EchoServer
I'd like to use websockets with at HttpServer. Here is the HttpHandler I came up with ... and the corresponding 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 类是:
The EchoServer class is:
@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 不会被交换.
I don't have much hope that this will work because I don't think the connection IDs are exchanged.
您将如何完成此代码以获得功能性的 websocket 连接?
How would you complete this code to get a functional websocket connection?
推荐答案
将 com.sun.net.httpserver.HttpExchange
用于 WebSocket 是行不通的.
Using com.sun.net.httpserver.HttpExchange
for WebSocket isn't going to work.
该 API 不允许真正升级的连接.换句话说,一个没有 HTTP 连接编码或封装的连接(例如 chunked 或 gziped 等)
That API for that doesn't allow for a true upgraded connection. In other words, a connection where there is no HTTP connection encoding or encapsulation (such as chunked, or gziped, etc)
此外,您对 WebSocket 升级的协议处理无效,没有浏览器会发现该响应有效并继续升级.
Also, your protocol handling of the WebSocket upgrade isn't valid, no browser out there will find that response to be valid and continue the upgrade.
代码中有 2 个示例.
2 examples in your code.
Sec-WebSocket-Accept
必须提供,并根据传入的请求头正确计算Sec-WebSocket-Protocol
必须提供,如果传入的请求定义了一个
Sec-WebSocket-Accept
must be provided, and be correctly calculated from the incoming request headersSec-WebSocket-Protocol
must be provided, if the incoming request has one defined
这篇关于如何构建一个 websocket HttpHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!