Netty With WebSocket
В прошлой статье мы говорили о том, как использоватьNetty
разработатьHttp
файловый сервер, который содержит информацию о том, как использоватьNetty
Предоставленный класс компонента для анализаHttp
После протокола обрабатывается запрос, а затем кодек и передача продолжаются через существующие компоненты.
В этой статье в основном рассказывается о том, как использоватьNetty
ИнтегрироватьWebSocket
сделай одинDEMO
статья. Фактически, какHttp
Такой же,Netty
ВерноWebSocket
Инкапсуляция предоставляет несколько удобных и простых в использовании компонентов, которые вы можете использовать, пока пишете код. В этот момент я еще раз испыталNetty
высокой масштабируемости.
Затем в этой статье будет описано содержание
- что
WebSocket
. -
WebSocket
а такжеHttp
разница. - зачем нам нужно
WebSocket
. -
Netty
а такжеWebSocket
интеграция между.
чтоWebSocket
Так большинство людей описывает это
WebSocket
даHTML5
Обеспечивает связь между браузером и серверомполнодуплексная связьсетевые технологии.
Это кажется довольно непонятным.HTML5
мы понимаем, но全双工通信
Мы не понимаем. Итак, давайте проанализируем, что это такоеWebSocket
.
Из того, что мы узнали раньше, мы знаемSocket
Это функциональный интерфейс между транспортным уровнем и приложением, через который мы можем использоватьTCP/IP
Стек протоколов отправляет и получает данные на транспортном уровне. ТакWebSocket
Какая связь с этим? отWebSocket
Буквально, мы можем разделить называетсяWeb
а такжеSocket
. может ты сможешьGET
да, не так ли?WebSocket
как будто бежитWeb
выше, ответственныйHttp
ВверхSocket
Спецификация связи?
Конечно!WebSocket
так сказать на основеHttp
протоколSocket
спецификации связи, обеспечивающие последующуюTCP Socket
Аналогичная функция, это может быть какTCP Socket
Он также вызывает стек протоколов нижнего уровня для произвольной отправки и получения данных. Но не думайWebSocket
даHttp
Обновленная версия (по причинам, которые будут описаны ниже). Фактически,WebSocket
основывается наTCP
Облегченный сетевой протокол связи, статус иHttp
равно.
зачем нам нужноWebSocket
?
Прежде всего, мы должны понимать, что появление новых вещей в той же области, скорее всего, не ниспровергнет прежнее, а продолжит совершенствоваться на плечах гигантов. а такжеWebSocket
оказывается, на самом деле, чтобы компенсироватьHttp
Дефекты.
согласно сWebSocket
введение, мы знаем, что этополнодуплексная связьсетевые технологии. а такжеHttp
этополудуплексТехнология.Http
У этой технологии есть две особенности.
- Между клиентом и сервером одновременно допускается только односторонний поток данных
- Сервер не может активно отправлять данные клиенту и может использовать толькоответ на запросспособ «пассивно» отвечать на запросы клиентов.
полудуплексКакие проблемы это принесет нам? Если вы сделали информацию в режиме реального времени, это может быть более сложным для вас. Вообще говоря, общение в реальном времени требует взаимодействия между двумя сторонами, то есть вы можете отправить его ему, а он может отправить вам. Но очевидно,полудуплексОн может быть отправлен только от клиента к серверу, и сервер не может отправить его клиенту. Может быть, вы скажете, разве мой клиент не может время от времени обращаться к серверу?
В режиме реального времени, не болееWebSocket
В случае , метод «опроса» обычно используется для достижения равномерного обмена данными, то есть для непрерывного запроса к серверу. Если частота опроса относительно высока, то ее можно аппроксимироватьобщение в реальном времениЭффект
Однако недостаток опроса также очевиден.CPU
ресурсов, очень неэкономично.
так,WebSocket
этополнодуплексная связь.
WebSocket
специальность
Может быть, есть еще много людей, которые сомневаются: очевидно, я вижуWebSocket
основывается наHttp
взаимодействовать, его формат протокола не совпадает сHttp
Есть ли сходство? Не совсем. мы знаемHttp
По сути, это лидер нынешних протоколов интернет-коммуникаций, и нет никого. ноWebSocket
не использовал многоHttp
что-то, наоборот, имеет следующие характеристики
- первый
WebSocket
использует структуру бинарного фрейма, сHttp
структура совсем другая. Однако, чтобы облегчить продвижение и применение, мы должны взять на себя «бесплатную поездку» и изо всех сил стараться использовать привычки, насколько это возможно.Http
Подойди поближе, вот как это называетсяWeb
имея в виду. (Я объясню, почему автостоп ниже) - Второй,
WebSocket
Не похожSocket
использовать такIP+端口
метод, но продолжениеHttp
изURI
Формат. ноURL
не начинается сHttp
, ноws
а такжеwss
, которые являются открытым текстом и зашифрованы соответственноWebSocket
протокол. - Более того,
WebSocket
Порт по умолчанию по-прежнему используется80
а также443
. Поскольку текущий серверный брандмауэр в Интернете блокирует большинство портов, толькоHttp
из80
а также443
отпусти, такWebSocket
могукамуфляжсталиHttp
соглашениепроникатьБрандмауэр, установить соединение с сервером.
Процесс взаимодействия WebSocket
говорящийWebSocket
Когда дело доходит до характеристик , возможно, вы знаете немного о внутренней истории:WebSocket
на самом деле иHttp
Это не имеет большого значения, простоWebSocket
Зависит отHttp
«Слава» взлетела!
Не торопитесь, давайте посмотримWebSocket
последовательность взаимодействия. Вот интерактивная диаграмма общей картины:
мы видим,WebSocket
Есть и похожиеTCP
процесс рукопожатия. сначала он испускаетHttp
изGet
Запрос, ниже приведены подробности сообщения
GET /HTTP/1.1
Upgrader: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Set-WebSocket-Key: sNNdMgdc2VGJEKS
Set-WebSocket-Version: 13
В сообщении стоит обратить внимание на несколько полей
имя поля | использовать |
---|---|
Upgrade |
Установить какWebSocket , указывая на то, что вам нужно объяснить серверуHttp обновитесь доWebSocket протокол |
Sec-WebSocket-key |
Base64 Закодированное 16-байтовое случайное число, используемое для проверки правильностиWebSocket вместоHttp протокол |
Sec-WebSocket-Version |
указать использованиеWebSocket Номер версии протокола |
Затем, когда сервер получает сообщение от клиента, он начинает анализировать сообщение. В это время он знает из сообщения, что этоWebSocket
запрос. Итак, начните создавать специальную информацию о сообщении, содержание сообщения
HTTP/1.1 101 Switching Protocols
Upgrader: websocket
Connection: Upgrade
Set-WebSocket-Accept: fFBooB7FAkKLlXgrSz0BT3v4hq5s
Set-WebSocket-Location: ws://examples.com/
Поля сообщения все еще знакомы. но мы нашли101 Switching Protocols
Описание, которое возвращает сервер101
Код состояния, сообщающий клиенту, что он может продолжитьWebSocket
Полнодуплексная двусторонняя связь. Это эквивалентно тому, что клиент и сервер согласились использоватьWebSocket
Приходите пообщаться, его больше нетHttp
что случилось.
Затем выше возвращаетсяSet-WebSocket-Accept
Он используется для проверки сообщения запроса клиента, а также для предотвращения неправильного подключения. В частности, у клиентаSet-WebSocket-Key
провести специальнуюUUID
, а затем вычислитьSHA-1
Резюме. Таким образом, клиент также будет использовать это вычисление для сравнения информации ответа сервера, чтобы избежать ошибки аутентификации.
После завершения рукопожатия последующая передача данных прекращается.Http
сообщение, ноWebSocket
также отформатируйте двоичный фрейм.
Netty
ИнтегрироватьWebSocket
Прежде всего, мы используемNetty
Чтобы реализовать класс запуска на стороне сервера
WebSocketServer.java
public class WebSocketServer {
public void run(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch)
throws Exception {
// http 的解码器
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("http-codec",
new HttpServerCodec());
// 负责将 Http 的一些信息例如版本
// 和 Http 的内容继承一个 FullHttpRequesst
pipeline.addLast("aggregator",
new HttpObjectAggregator(65536));
// 大文件写入的类
ch.pipeline().addLast("http-chunked",
new ChunkedWriteHandler());
// websocket 处理类
pipeline.addLast("handler",
new WebSocketServerHandler());
}
});
// 监听端口
Channel ch = b.bind(port).sync().channel();
ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new WebSocketServer().run(8080);
}
}
Далее мы являемся процессором, реализующим логику обработкиWebSocketServerHandler.java
public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = Logger
.getLogger(WebSocketServerHandler.class.getName());
private WebSocketServerHandshaker handshaker;
@Override
public void messageReceived(ChannelHandlerContext ctx, Object msg)
throws Exception {
// 传统的HTTP接入(握手流程是走这里的)
if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg);
}
// WebSocket接入
else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
private void handleHttpRequest(ChannelHandlerContext ctx,
FullHttpRequest req) throws Exception {
// 如果HTTP解码失败,返回HHTP异常
if (!req.getDecoderResult().isSuccess()
|| (!"websocket".equals(req.headers().get("Upgrade")))) {
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1,
BAD_REQUEST));
return;
}
// 构造握手响应返回,目前是本机的地址
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
"ws://localhost:8080/websocket", null, false);
handshaker = wsFactory.newHandshaker(req);
if (handshaker == null) {
WebSocketServerHandshakerFactory
.sendUnsupportedWebSocketVersionResponse(ctx.channel());
} else {
handshaker.handshake(ctx.channel(), req);
}
}
private void handleWebSocketFrame(ChannelHandlerContext ctx,
WebSocketFrame frame) {
// 判断是否是关闭链路的指令
if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(),
(CloseWebSocketFrame) frame.retain());
return;
}
// 判断是否是Ping消息
if (frame instanceof PingWebSocketFrame) {
ctx.channel().write(
new PongWebSocketFrame(frame.content().retain()));
return;
}
// 本例程仅支持文本消息,不支持二进制消息
if (!(frame instanceof TextWebSocketFrame)) {
throw new UnsupportedOperationException(String.format(
"%s frame types not supported", frame.getClass().getName()));
}
// 返回应答消息
String request = ((TextWebSocketFrame) frame).text();
if (logger.isLoggable(Level.FINE)) {
logger.fine(String.format("%s received %s", ctx.channel(), request));
}
ctx.channel().write(
new TextWebSocketFrame(request
+ " , 欢迎使用Netty WebSocket服务,现在时刻:"
+ new java.util.Date().toString()));
}
private static void sendHttpResponse(ChannelHandlerContext ctx,
FullHttpRequest req, FullHttpResponse res) {
// 返回应答给客户端
if (res.getStatus().code() != 200) {
ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(),
CharsetUtil.UTF_8);
res.content().writeBytes(buf);
buf.release();
setContentLength(res, res.content().readableBytes());
}
// 如果是非Keep-Alive,关闭连接
ChannelFuture f = ctx.channel().writeAndFlush(res);
if (!isKeepAlive(req) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
}
}
На самом деле приведенный выше код относительно ясен. В основном делится на два процесса:
метод | иллюстрировать |
---|---|
handleHttpRequest() |
Ответственный за ответ на запрос рукопожатия клиента |
handleWebSocketFrame() |
ответственный за обработкуWebSocket Новости |
во время обработкиhandleWebSocketFrame()
В основном отвечает за несколько операций:
- Это команда закрыть ссылку
- Является ли это сообщением сердцебиения
- Является ли это содержанием сообщения
Эпилог
Эта статья предназначалась дляNetty
а такжеWebSocket
интегрированных. Но я узнал, чтоWebSocket
Рост и причины его популярности гораздо менее просты, чем предполагалось. Вот и решил копнуть глубже. Обобщить содержание статьи
-
WebSocket
эквивалентноHttp
Патч длительного подключения для протокола. это иHttp
Существующие общие черты (использование рукопожатия соединенияGet
Запрос), первый - это решитьHttp
Не поддерживает отсутствие длинных подключений, решитьHttp
Характеристики коротких ссылок, не отвечающих спросу. - Во внутренней структуре,
WebSocket
а такжеHttp
Есть много различий. Чтобы повысить эффективность,WebSocket
Используя двоичные кадры, их легче понять и передать. - использовать
Netty
Процессор может быть реализован быстро упакованнымWebSocket
Приложения
конец!