Netty websocket и отдых в одном приложении Java - PullRequest
0 голосов
/ 11 октября 2018

У меня есть приложение на Java, которое предоставляет сервисы REST.Я хочу добавить новую функцию в том же приложении для обработки запросов веб-сокетов (используя netty) вместе с существующими службами REST.Как я могу сделать это, не меняя мои REST-сервисы?

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Вы можете использовать обработчик перед обработчиком, который получает запросы http.Основная задача этого обработчика - определить, содержит ли http-запрос заголовки обновления WebSocket.В этом случае он завершит рукопожатие и продолжит обрабатывать кадры веб-сокета, в противном случае он будет передавать запросы http следующему обработчику следующим образом:

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;

public class WebSocketServerHandler extends ChannelInboundHandlerAdapter {
    private WebSocketServerHandshaker handshaker;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof HttpRequest) {
            HttpRequest httpRequest = (HttpRequest) msg;
            HttpMethod requestMethod = httpRequest.method();

            if (containsUpgradeHeaders(httpRequest)) {
                if (HttpMethod.GET == requestMethod) {
                    // Handshake
                    WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                            getWebSocketLocation(httpRequest), null, false, Integer.MAX_VALUE);
                    handshaker = wsFactory.newHandshaker(httpRequest);
                    if (handshaker == null) {
                        WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
                    } else {
                        handshaker.handshake(ctx.channel(), httpRequest);
                    }

                }
            } else {
                //Let the http handler handle the request
                ctx.fireChannelRead(msg);
            }

        } else if (msg instanceof WebSocketFrame) {
            handleWebSocketFrame(ctx, (WebSocketFrame) msg);
        } else {
            throw new IllegalStateException("unknown message: " + msg);
        }
    }

    private boolean containsUpgradeHeaders(HttpRequest httpRequest) {
        HttpHeaders headers = httpRequest.headers();
        return headers.containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE, true) && headers
                .containsValue(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET, true);
    }

    private static String getWebSocketLocation(HttpRequest req) {
        return "ws://" + req.headers().get(HttpHeaderNames.HOST);
    }

    private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        //handle the websocket frame
    }
}

Или вы можете использовать другой обработчик для обработкифреймы websocket, заменив обработчик запросов http на обработчик фреймов WebSocket после завершения рукопожатия.

0 голосов
/ 11 октября 2018

Есть два способа сделать это без изменения службы REST:

  1. Я бы посоветовал вам настроить обычный сервер netty websocket и запустить его параллельно на другом порту (это может произойти вто же приложение).

  2. Более сложным и неэффективным решением было бы написать сервер netty http / websocket, который работает на порте по умолчанию (80/443) и отправляет все запросы REST наВаш ОТДЫХТаким образом, в основном вы должны написать своего рода HTTP-прокси, который также размещает сервер веб-сокетов (может также происходить в том же приложении).

Здесь является примером того, какнаписать сервер netty websocket.

...