Skip to content

升级 WebSocket 🌐

This content is not available in your language yet.

Feat 支持通过通过 HttpRequest.upgrade 方法将 HTTP 请求升级为 WebSocket。

操作示例如下:

WebSocketDemo.java
public class WebSocketDemo {
public static void main(String[] args) {
Feat.httpServer().httpHandler(request -> {
request.upgrade(new WebSocketUpgrade() {
@Override
public void handleTextMessage(WebSocketRequest request, WebSocketResponse response, String message) {
response.sendTextMessage("接受到客户端消息:" + message);
}
});
}).listen();
}
}

启动程序后,可访问:WebSocket 在线测试 验证运行效果。

hello world

构造方法

WebSocketUpgrade 提供了两个构造方法,分别如下:

public WebSocketUpgrade() {
this(120000);
}
public WebSocketUpgrade(long idleTimeout) {
this.idleTimeout = idleTimeout;
}

用户可在进行 WebSocket 升级时,通过构造方法传入 idleTimeout 参数,设置 WebSocket 连接的空闲超时时间。 其中无参构造方法默认设置空闲超时时间为 120000 毫秒,即:2 分钟。

当 WebSocket 连接空闲时间超过 idleTimeout 时,Feat 会主动关闭该连接。

消息处理

WebSocketUpgrade 提供了两个消息处理方法,分别如下:

public void handle(WebSocketRequest request, WebSocketResponse response, CompletableFuture<Object> completableFuture) throws Throwable {
try {
handle(request, response);
} finally {
completableFuture.complete(null);
}
}
public void handle(WebSocketRequest request, WebSocketResponse response) throws Throwable {
...
}

如果用户需要采用异步方式处理 WebSocket 消息,可重写带 CompletableFuture<Object> 入参的 handle 方法,并在异步处理完成后,调用 completableFuture.complete(null) 方法。

若需要同步处理 WebSocket 消息,可重写 handle(WebSocketRequest request, WebSocketResponse response) 方法。

为便于开发人员使用,WebSocketUpgrade 已经默认实现了 handle(WebSocketRequest request, WebSocketResponse response) 方法,用户可按需重写相应的方法。

public void handle(WebSocketRequest request, WebSocketResponse response) throws Throwable {
try {
switch (request.getFrameOpcode()) {
case WebSocketUtil.OPCODE_TEXT:
handleTextMessage(request, response, new String(request.getPayload(), StandardCharsets.UTF_8));
break;
case WebSocketUtil.OPCODE_BINARY:
handleBinaryMessage(request, response, request.getPayload());
break;
case WebSocketUtil.OPCODE_CLOSE:
try {
onClose(request, response, new CloseReason(request.getPayload()));
} finally {
response.close();
}
break;
case WebSocketUtil.OPCODE_PING:
handlePing(request, response);
break;
case WebSocketUtil.OPCODE_PONG:
handlePong(request, response);
break;
case WebSocketUtil.OPCODE_CONTINUE:
handleContinueMessage(request, response, request.getPayload());
break;
default:
throw new UnsupportedOperationException();
}
} catch (Throwable throwable) {
onError(request, throwable);
}
}

请求路由

在实际场景下,用户可能需要将不同的 WebSocket 消息路由到不同的处理方法, 以及存在 Http 请求和 WebSocket 请求共存的情况。

此时可以采用 Router 来实现请求路由,示例如下:

WebSocketRouterDemo.java
public class WebSocketRouterDemo {
public static void main(String[] args) {
Router router = new Router();
router.route("/ws1", request -> {
request.upgrade(new WebSocketUpgrade() {
@Override
public void handleTextMessage(WebSocketRequest request, WebSocketResponse response, String message) {
response.sendTextMessage("ws1接受到客户端消息:" + message);
}
});
}).route("/ws2", request -> {
request.upgrade(new WebSocketUpgrade() {
@Override
public void handleTextMessage(WebSocketRequest request, WebSocketResponse response, String message) {
response.sendTextMessage("ws2接受到客户端消息:" + message);
}
});
}).route("/http", request -> {
request.getResponse().write("http".getBytes());
});
Feat.httpServer().httpHandler(router).listen();
}
}