From 6d50c358c99865b463a0f772f04d3e13a8bc50e1 Mon Sep 17 00:00:00 2001 From: minux Date: Wed, 14 Jun 2023 23:16:17 +0900 Subject: [PATCH] Add WebSocketServiceHandler (#4954) I need to add `WebSocketServiceHandler` and refactor `WebSocketHandler` before releasing a new version. --- .../common/websocket/WebSocketHandler.java | 37 +++++++++++++++++++ .../common}/websocket/WebSocketWrapper.java | 6 +-- .../armeria/server/Http1RequestDecoder.java | 2 +- ...va => WebSocketSessionChannelHandler.java} | 8 ++-- .../server/websocket/WebSocketService.java | 13 ++++--- .../websocket/WebSocketServiceBuilder.java | 4 +- ...dler.java => WebSocketServiceHandler.java} | 12 ++---- .../websocket/WebSocketServiceTest.java | 2 +- .../it/websocket/WebSocketServiceItTest.java | 4 +- 9 files changed, 60 insertions(+), 28 deletions(-) create mode 100644 core/src/main/java/com/linecorp/armeria/common/websocket/WebSocketHandler.java rename core/src/main/java/com/linecorp/armeria/{server => internal/common}/websocket/WebSocketWrapper.java (91%) rename core/src/main/java/com/linecorp/armeria/server/{WebSocketSessionHandler.java => WebSocketSessionChannelHandler.java} (94%) rename core/src/main/java/com/linecorp/armeria/server/websocket/{WebSocketHandler.java => WebSocketServiceHandler.java} (73%) diff --git a/core/src/main/java/com/linecorp/armeria/common/websocket/WebSocketHandler.java b/core/src/main/java/com/linecorp/armeria/common/websocket/WebSocketHandler.java new file mode 100644 index 00000000000..80155e02c34 --- /dev/null +++ b/core/src/main/java/com/linecorp/armeria/common/websocket/WebSocketHandler.java @@ -0,0 +1,37 @@ +/* + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package com.linecorp.armeria.common.websocket; + +import com.linecorp.armeria.common.RequestContext; +import com.linecorp.armeria.common.annotation.UnstableApi; +import com.linecorp.armeria.server.websocket.WebSocketServiceHandler; + +/** + * Implement this interface to handle incoming {@link WebSocketFrame}s from the peer and + * send {@link WebSocketFrame}s to the peer. + * + * @see WebSocketServiceHandler + */ +@UnstableApi +@FunctionalInterface +public interface WebSocketHandler { + + /** + * Handles the incoming {@link WebSocket} and returns {@link WebSocket} created via + * {@link WebSocket#streaming()} to send {@link WebSocketFrame}s. + */ + WebSocket handle(T ctx, WebSocket in); +} diff --git a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketWrapper.java b/core/src/main/java/com/linecorp/armeria/internal/common/websocket/WebSocketWrapper.java similarity index 91% rename from core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketWrapper.java rename to core/src/main/java/com/linecorp/armeria/internal/common/websocket/WebSocketWrapper.java index 207ec566c46..256aa1d3bce 100644 --- a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketWrapper.java +++ b/core/src/main/java/com/linecorp/armeria/internal/common/websocket/WebSocketWrapper.java @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ -package com.linecorp.armeria.server.websocket; +package com.linecorp.armeria.internal.common.websocket; import java.util.concurrent.CompletableFuture; @@ -26,11 +26,11 @@ import io.netty.util.concurrent.EventExecutor; -final class WebSocketWrapper implements WebSocket { +public final class WebSocketWrapper implements WebSocket { private final StreamMessage delegate; - WebSocketWrapper(StreamMessage delegate) { + public WebSocketWrapper(StreamMessage delegate) { this.delegate = delegate; } diff --git a/core/src/main/java/com/linecorp/armeria/server/Http1RequestDecoder.java b/core/src/main/java/com/linecorp/armeria/server/Http1RequestDecoder.java index 55dd183d09e..f564480c32a 100644 --- a/core/src/main/java/com/linecorp/armeria/server/Http1RequestDecoder.java +++ b/core/src/main/java/com/linecorp/armeria/server/Http1RequestDecoder.java @@ -248,7 +248,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception assert encoder instanceof ServerHttp1ObjectEncoder; ((ServerHttp1ObjectEncoder) encoder).webSocketUpgrading(); final ChannelPipeline pipeline = ctx.pipeline(); - pipeline.replace(this, null, new WebSocketSessionHandler( + pipeline.replace(this, null, new WebSocketSessionChannelHandler( webSocketRequest, encoder, serviceConfig)); if (pipeline.get(HttpServerUpgradeHandler.class) != null) { pipeline.remove(HttpServerUpgradeHandler.class); diff --git a/core/src/main/java/com/linecorp/armeria/server/WebSocketSessionHandler.java b/core/src/main/java/com/linecorp/armeria/server/WebSocketSessionChannelHandler.java similarity index 94% rename from core/src/main/java/com/linecorp/armeria/server/WebSocketSessionHandler.java rename to core/src/main/java/com/linecorp/armeria/server/WebSocketSessionChannelHandler.java index dc097d556e1..e348d1c1b06 100644 --- a/core/src/main/java/com/linecorp/armeria/server/WebSocketSessionHandler.java +++ b/core/src/main/java/com/linecorp/armeria/server/WebSocketSessionChannelHandler.java @@ -38,16 +38,16 @@ import io.netty.handler.codec.http2.Http2Error; import io.netty.util.ReferenceCountUtil; -final class WebSocketSessionHandler extends ChannelDuplexHandler { +final class WebSocketSessionChannelHandler extends ChannelDuplexHandler { - private static final Logger logger = LoggerFactory.getLogger(WebSocketSessionHandler.class); + private static final Logger logger = LoggerFactory.getLogger(WebSocketSessionChannelHandler.class); private final StreamingDecodedHttpRequest req; private final ServerHttpObjectEncoder encoder; private final ServiceConfig serviceConfig; - WebSocketSessionHandler(StreamingDecodedHttpRequest req, ServerHttpObjectEncoder encoder, - ServiceConfig serviceConfig) { + WebSocketSessionChannelHandler(StreamingDecodedHttpRequest req, ServerHttpObjectEncoder encoder, + ServiceConfig serviceConfig) { this.req = req; this.encoder = encoder; this.serviceConfig = serviceConfig; diff --git a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketService.java b/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketService.java index 46c5948d02e..a5aa42d36d7 100644 --- a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketService.java +++ b/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketService.java @@ -48,6 +48,7 @@ import com.linecorp.armeria.common.websocket.WebSocketFrame; import com.linecorp.armeria.internal.common.websocket.WebSocketFrameDecoder; import com.linecorp.armeria.internal.common.websocket.WebSocketFrameEncoder; +import com.linecorp.armeria.internal.common.websocket.WebSocketWrapper; import com.linecorp.armeria.server.AbstractHttpService; import com.linecorp.armeria.server.HttpService; import com.linecorp.armeria.server.ServiceRequestContext; @@ -80,27 +81,27 @@ public final class WebSocketService extends AbstractHttpService { private static final WebSocketFrameEncoder encoder = WebSocketFrameEncoder.of(false); /** - * Returns a new {@link WebSocketService} with the {@link WebSocketHandler}. + * Returns a new {@link WebSocketService} with the {@link WebSocketServiceHandler}. */ - public static WebSocketService of(WebSocketHandler handler) { + public static WebSocketService of(WebSocketServiceHandler handler) { return new WebSocketServiceBuilder(handler).build(); } /** - * Returns a new {@link WebSocketServiceBuilder} with the {@link WebSocketHandler}. + * Returns a new {@link WebSocketServiceBuilder} with the {@link WebSocketServiceHandler}. */ - public static WebSocketServiceBuilder builder(WebSocketHandler handler) { + public static WebSocketServiceBuilder builder(WebSocketServiceHandler handler) { return new WebSocketServiceBuilder(handler); } - private final WebSocketHandler handler; + private final WebSocketServiceHandler handler; private final int maxFramePayloadLength; private final boolean allowMaskMismatch; private final Set subprotocols; private final Set allowedOrigins; private final boolean allowAnyOrigin; - WebSocketService(WebSocketHandler handler, int maxFramePayloadLength, boolean allowMaskMismatch, + WebSocketService(WebSocketServiceHandler handler, int maxFramePayloadLength, boolean allowMaskMismatch, Set subprotocols, Set allowedOrigins, boolean allowAnyOrigin) { this.handler = handler; this.maxFramePayloadLength = maxFramePayloadLength; diff --git a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceBuilder.java b/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceBuilder.java index 58e4383dee2..41c4f8361a5 100644 --- a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceBuilder.java @@ -41,14 +41,14 @@ public final class WebSocketServiceBuilder { static final int DEFAULT_MAX_FRAME_PAYLOAD_LENGTH = 65535; // 64 * 1024 -1 - private final WebSocketHandler handler; + private final WebSocketServiceHandler handler; private int maxFramePayloadLength = DEFAULT_MAX_FRAME_PAYLOAD_LENGTH; private boolean allowMaskMismatch; private Set subprotocols = ImmutableSet.of(); private Set allowedOrigins = ImmutableSet.of(); - WebSocketServiceBuilder(WebSocketHandler handler) { + WebSocketServiceBuilder(WebSocketServiceHandler handler) { this.handler = requireNonNull(handler, "handler"); } diff --git a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketHandler.java b/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceHandler.java similarity index 73% rename from core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketHandler.java rename to core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceHandler.java index 38978bbeba3..02aa860a226 100644 --- a/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketHandler.java +++ b/core/src/main/java/com/linecorp/armeria/server/websocket/WebSocketServiceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 LINE Corporation + * Copyright 2023 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -16,8 +16,8 @@ package com.linecorp.armeria.server.websocket; import com.linecorp.armeria.common.annotation.UnstableApi; -import com.linecorp.armeria.common.websocket.WebSocket; import com.linecorp.armeria.common.websocket.WebSocketFrame; +import com.linecorp.armeria.common.websocket.WebSocketHandler; import com.linecorp.armeria.server.ServiceRequestContext; /** @@ -28,11 +28,5 @@ */ @UnstableApi @FunctionalInterface -public interface WebSocketHandler { - - /** - * Handles the incoming {@link WebSocket} and returns {@link WebSocket} created via - * {@link WebSocket#streaming()} to send {@link WebSocketFrame}s. - */ - WebSocket handle(ServiceRequestContext ctx, WebSocket in); +public interface WebSocketServiceHandler extends WebSocketHandler { } diff --git a/core/src/test/java/com/linecorp/armeria/server/websocket/WebSocketServiceTest.java b/core/src/test/java/com/linecorp/armeria/server/websocket/WebSocketServiceTest.java index 7eef5f0f7d6..089bc929a0d 100644 --- a/core/src/test/java/com/linecorp/armeria/server/websocket/WebSocketServiceTest.java +++ b/core/src/test/java/com/linecorp/armeria/server/websocket/WebSocketServiceTest.java @@ -128,7 +128,7 @@ private HttpData toHttpData(WebSocketFrame frame) { return HttpData.wrap(encoder.encode(ctx, frame)); } - static class AbstractWebSocketHandler implements WebSocketHandler { + static class AbstractWebSocketHandler implements WebSocketServiceHandler { @Override public WebSocket handle(ServiceRequestContext ctx, WebSocket in) { diff --git a/it/websocket/src/test/java/com/linecorp/armeria/it/websocket/WebSocketServiceItTest.java b/it/websocket/src/test/java/com/linecorp/armeria/it/websocket/WebSocketServiceItTest.java index 73269d2aef7..568c4cc61a2 100644 --- a/it/websocket/src/test/java/com/linecorp/armeria/it/websocket/WebSocketServiceItTest.java +++ b/it/websocket/src/test/java/com/linecorp/armeria/it/websocket/WebSocketServiceItTest.java @@ -51,9 +51,9 @@ import com.linecorp.armeria.common.websocket.WebSocketWriter; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; -import com.linecorp.armeria.server.websocket.WebSocketHandler; import com.linecorp.armeria.server.websocket.WebSocketProtocolViolationException; import com.linecorp.armeria.server.websocket.WebSocketService; +import com.linecorp.armeria.server.websocket.WebSocketServiceHandler; import com.linecorp.armeria.testing.junit5.server.ServerExtension; class WebSocketServiceItTest { @@ -227,7 +227,7 @@ public void onClose(int code, String reason, boolean remote) { public void onError(Exception ex) {} } - static final class WebSocketEchoHandler implements WebSocketHandler { + static final class WebSocketEchoHandler implements WebSocketServiceHandler { @Override public WebSocket handle(ServiceRequestContext ctx, WebSocket in) {