Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность
Введение
В предыдущей статье мы использовали netty для создания сервера, который может обрабатывать протокол веб-сокета, В этом сервере мы создали специальный обработчик для обработки запросов HTTP или веб-сокета.
Обработка двух разных запросов в одном обработчике может быть невыносимой для некоторых людей с чистотой кода. Итак, можно ли использовать разные обработчики для обычных запросов HTTP и запросов веб-сокетов? Ответ положительный.
Обработка сообщений Netty
Мы знаем, что вся обработка сообщений в netty реализована обработчиком.Для удобства netty предоставляет простой класс обработки сообщений SimpleChannelInboundHandler.Вы можете переписать метод channelRead0, унаследовав его:
protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception;
Давайте еще раз посмотрим на определение SimpleChannelInboundHandler:
public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter
Можно видеть, что сам SimpleChannelInboundHandler имеет общий I, и это I является направлением, которое мы хотим исследовать.
Если мы хотим использовать этот обработчик для обработки всех сообщений, то для меня можно установить значение Object.
Если нам нужно иметь дело только со строковыми сообщениями, мы можем сделать это:
public class StringHandler extends
SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String message)
throws Exception {
System.out.println(message);
}
}
Аналогичным образом, если вы хотите обрабатывать как сообщения HTTP, так и сообщения WebSocket, вам просто нужно установить для I другой тип.
Для WebSocketFrame имеем:
public class Server2FrameHandler extends SimpleChannelInboundHandler<WebSocketFrame>
Для FullHttpRequest у нас есть:
public class Server2HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest>
Обработка WebSocketFrame
Для сообщений WebSocketFrame мы знаем из предыдущего раздела, что он имеет 6 типов, а именно:
BinaryWebSocketFrame
CloseWebSocketFrame
ContinuationWebSocketFrame
PingWebSocketFrame
PongWebSocketFrame
TextWebSocketFrame
Те, которые действительно содержат содержимое, это TextWebSocketFrame и BinaryWebSocketFrame, Здесь мы имеем дело с TextWebSocketFrame специально:
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
if (frame instanceof TextWebSocketFrame) {
// 将接收到的消息转换成为大写
String request = ((TextWebSocketFrame) frame).text();
ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));
} else {
String message = "不支持的Frame类型: " + frame.getClass().getName();
throw new UnsupportedOperationException(message);
}
}
Обработка HTTP
Для FullHttpRequest в запросе HTTP мы просто устанавливаем обычный поток обработки запроса службы HTTP.
Я не буду вдаваться в подробности здесь.
Кодер и декодер
Подождите, мы что-то забыли? Да, это кодер и декодер.
В предыдущем разделе мы использовали WebSocketServerHandshaker для кодирования и декодирования сообщений веб-сокета. Однако на самом деле он находится в нашем пользовательском коде хедлера, который немного неудобен в использовании.
Не беда, netty предоставляет нам класс WebSocketServerProtocolHandler, отвечающий за кодирование и декодирование вебсокетов.
Помимо обработки обычного рукопожатия веб-сокета, класс WebSocketServerProtocolHandler также обрабатывает несколько распространенных типов сообщений, таких как Close, Ping и Pong. И нам нужно сосредоточиться только на реальных сообщениях бизнес-логики, что очень удобно.
Что касается оставшихся данных текстового или двоичного фрейма, они будут переданы следующему обработчику в конвейере для обработки.
Среди них Handshake имеет два состояния, а именно:
HANDSHAKE_COMPLETE и HANDSHAKE_TIMEOUT.
И HandshakeComplete содержит информацию requestUri, requestHeaders и selectedSubprotocol.
Наконец, добавьте WebSocketServerProtocolHandler в конвейер и, наконец, получите:
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
pipeline.addLast(new Server2HttpHandler());
pipeline.addLast(new Server2FrameHandler());
}
Суммировать
Сервер, который разделяет HTTP-запросы и запросы webSocket, готов. Простой и интуитивно понятный мир, к которому стремится программист!
Примеры этой статьи могут относиться к:learn-netty4
Эта статья была включена вWoohoo.Floyd Press.com/24-Netty-Towering…
Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!
Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!