如今, Netty已用于Internet上的各种应用程序中,以处理数千(即使不是数百万)的聊天对话,包括Minecraft , Twitter和许多其他应用程序在内的多人游戏。 但是,它并没有在开发企业应用程序的企业程序员的头脑中走得很远。

我相信Netty可以引入一种新的功能,这是其他解决方案无法比拟的,因为它具有完全双向的文本和二进制非HTTP数据传输功能,并且比传统的“每线程线程数”支持更多的并发客户端”服务器。

您可能知道Netty在WebSockets方面的能力,但是您知道它可以像传统的Web服务器一样出色地工作吗? 由于其非常周到的设计,通过在其管道中添加适当的处理程序,Netty几乎可以处理任何流量。 它还可以同时处理多种类型,例如同时在同一端口上处理WebSocket和HTTP。 通过将这些结合在一起,程序员可以免于处理诸如CORS(跨源资源共享)之类的麻烦,当浏览器尝试向未从其下载的服务器发出请求时,这些麻烦可以抬头。

净值的力量

为了显示其转换企业应用程序的功能,我整理了一个代码示例,显示了Web的传统示例之一,该示例检索股价。

其他应用程序必须发出AJAX请求,轮询,具有刷新按钮等以更新价格。 WebSockets消除了任何这些需求。 创建持续开放的双向连接后,客户端和服务器都可以在需要时彼此对话,而无需任何协商。 因此,客户端让服务器知道任何用户何时更改标准,并且只要相关数据基于该标准发生变化,服务器就会更新客户端。

  • 您可以在此处找到功能齐全的代码。

我为客户端设置了一些基于JSON的协议,以使服务器知道用户的决定。 要将新符号添加到服务器正在监视客户端的列表中,只需要一个简单的调用即可。 这是一个例子:

doSend('{"command":"add", "tickerSymbol":"GOOG"}');

这会将符号添加到列表中。 服务器的下一次更新将在其数据中包括新符号的当前股价(来自Yahoo Finance的REST API)。 删除项目同样容易:

doSend('{"command":"remove", "tickerSymbol":"GOOG"}');

使用这两个命令,客户端可以控制服务器正在为每个用户监视的符号列表。 在Netty处理程序的服务器端,程序员要考虑多个用户的唯一工作是确保为每个新连接创建一个新的处理程序,并且在不共享数据的地方不使用静态成员。 。 除非另有说明,否则Netty假定处理程序不可共享。

让我们看看如何为Netty管道定义处理程序。 这来自StockTickerServer类:

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast("encoder", new HttpResponseEncoder());
p.addLast("decoder", new HttpRequestDecoder());
p.addLast("aggregator", new HttpObjectAggregator(65536));
p.addLast("handler", new StockTickerServerHandler());
}
});

这里的顺序非常重要,因为管道中的每个处理程序都有机会处理(或不处理)数据并将其传递给下一个处理程序。 股票行情处理程序位于底部,因为它是将数据发送回客户端的程序,因此位于管道的末端。 通过创建处理程序的新实例,每个新连接都将获得每个处理程序自己的实例。 如果处理程序是无状态的并且是线程安全的,则可以在适用的情况下使用单例代替以节省内存。 我使用的处理程序中没有一个是可共享的,因此这里没有显示示例。

Netty作为Web服务器

使用一些技巧来使Netty同时处理HTTP和WebSocket通信。

1. StockTickerServerHandler扩展了SimpleChannelInboundHandler <Object>

这告诉Netty,我们希望所有流量都到达此处理程序。 否则,如果只想处理HTTP通信,则可以使用SimpleChannelInboundHandler <FullHttpRequest>;如果只想处理WebSocket通信,则可以使用SimpleChannelInboundHandler <WebSocketFrame>。

2. channelRead0(通道读取为零)方法

@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) {
this.handleHttpRequest(ctx, (FullHttpRequest)msg);
} else if (msg instanceof WebSocketFrame) {
this.handleWebSocketFrame(ctx, (WebSocketFrame)msg);
}
}

这使我们能够根据每种协议处理HTTP和WebSocket通信。 handleHttpRequest提供HTML,图像,CSS,JavaScript和所有其他正常的网络流量,handleWebSocketFrame指出了如何处理从客户端发送的自定义消息。

3.哑剧类型

Netty没有内置对处理mime类型的支持,因为WebSocket调用本质上并不需要它们。

我添加了Apache的mime类型文件的稍作修改的版本,并静态加载了它。 我正在负载上进行同步,因为如果需要,Netty可以在池的开头创建很多处理程序,并且构造函数可以同时由多个处理程序执行。 由于该字段是静态的,因此在映射变为非null之前,可以对其进行多次加载。 同步静态锁(不是类的当前实例)可以防止这种情况的发生。

其他详情

handleWebSocketFrame方法处理WebSocket协议定义的不同“已知”帧类型。 收到全文框后,我会将其传递给我创建的接口的实现者,以指定如何处理业务逻辑。

该代码存在于StockTickerMessageHandler中。 它创建一个后台线程来检索股票报价并将其发送给客户端,并处理客户端发送的命令。

那里有一些凌乱的代码,用于处理Yahoo发送的Gzip压缩数据并解析服务返回的JSON,以及一些使用java.util.concurrent类(例如Executor,AtomicBoolean,AtomicReference和CopyOnWriteArrayList)的代码来保持后台线程和Netty处理程序彼此踩踏,因为它们共享有关通道和当前符号列表的详细信息。

我还使用Gson将传入的JSON转换为POJO,以便更轻松地对其进行处理。 除此之外,这只是本例的业务目的。

关于身份验证的注意事项

我没有时间向此示例添加身份验证。 如果这样做的话,我会使用Shiro ,它是一种功能强大的身份验证/授权/密码框架,可与普通应用程序和Web应用程序一起使用。 还缺少HTTPS支持,因为这是检查股票价格的公共应用程序。 有添加HTTPS(和WSS)的例子在这里 。

使用JavaScript WebSockets很难(如果不是不可能的话)的一件事是发送身份验证数据以及升级请求(即调用新的WebSocket(uri))。 因此,通常像通常的网站一样首先发送HTTPS POST并设置auth cookie令牌。 这样,当发送升级请求时,cookie会自动发送。 使用身份验证时,请记住使用HTTPS和WSS而不是HTTP和WS来保护数据。 身份验证到位后,就变成了在必要时检查经过身份验证的用户的问题,注意某些流量应始终通过(HTML,图像等)。

  • 代码项目

结论

Netty已成为构建新应用程序的一种高性能,改变游戏规则的方法。 通过利用WebSockets提供的功能,当今的企业应用程序可以比现在更具交互性。 我希望您喜欢这个进入Netty的小冒险,并请原谅糟糕的浏览器客户端,我只是没有时间为此示例制作一个不错的Backbone.js客户端应用程序。

谢谢!

翻译自: https://www.javacodegeeks.com/2015/03/netty-a-different-kind-of-websocket-server.html

Netty:另一种Web(套接字)服务器相关推荐

  1. stomp java客户端_Stomp-Spring服务器端的Web套接字Java客户端

    stomp java客户端 问题: 为了分析问题,我不得不编写一个简单的Java Web套接字客户端站点代码,并使用基于stomp的Web套接字代理连接到服务器端基于Spring的应用程序. 解决方案 ...

  2. Stomp-Spring服务器端的Web套接字Java客户端

    问题: 为了分析问题,我不得不编写一个简单的Java Web套接字客户端站点代码,并使用基于stomp的Web套接字代理连接到服务器端基于Spring的应用程序. 解决方案: pom.xml < ...

  3. Dart的套接字与web套接字

    套接字 首先在项目中建三个dart文件,如下图 main.dart中的代码如下 import 'dart:io'; import 'dart:convert';main(List<String& ...

  4. Java套接字程序_java – 通过Web套接字进行应用程序到应用程序的通信

    我通过Web套接字(没有浏览器工作)获得应用程序到应用程序的通信有些麻烦.由于这似乎不是最常用的网络套接字应用程序,我想知道是否有人有这方面的经验. 为什么我要使用网络套接字? 由于防火墙问题,我需要 ...

  5. java 函数式编程 示例_Java套接字编程–套接字服务器,客户端示例

    java 函数式编程 示例 Welcome to Java Socket programming example. Every server is a program that runs on a s ...

  6. c 服务器和android客户端,通过TCP与c + +(套接字服务器)conect android(套接字客户端)...

    我有一个实现在大学项目中做,我不知道如何avchive它!我的问题就像标题所说的那样,通过套接字将C++与android连接起来.通过TCP与c + +(套接字服务器)conect android(套 ...

  7. WIN10 管家婆套接字服务器 自启动

    开始 --运行--gpedit.msc--计算机配置-windows设置--安全设置--本地策略--安全选项--用户帐户控制:以管理员批准模式运行所有管理员--禁用 添加套接字服务器的快捷方式到:c: ...

  8. 套接字服务器打开显示未知文件异常,TCP-socket异常情况

    在Unix下进行网络编程时,由于网络并非完全可靠,会遇到各种协议主流程外发生的各种错误. 而健壮的程序必须考虑到这些错误并正确处理,因此这里总结网络编程中可能发生的常见错误. TCP异常流程 总体 应 ...

  9. 一个简单的socket套接字服务器,Python

    (1)用Python实现一个简单的套接字socket服务器例子,该服务器在接受客户端连接后,每隔一秒从a到z的字符中随机选一个发送给客户端. import socketserver import ti ...

  10. 【Linux网络编程】网络基础 和 socket套接字 服务器与客户端 详细案例说明

    目录 前言 一.网络编程三要素 1.IP地址 2.通信协议 3.端口号 二.SOCKET套接字 SOCKET概述 SOCKET分类 三.代码实现 1.编程思路 2.建立服务器 服务器完整代码 3.建立 ...

最新文章

  1. SAP RETAIL 特征参数文件(Characteristic Profile) II
  2. GPU深度发掘(一)::GPGPU数学基础教程
  3. 计算机网络中数据的传递过程
  4. nit计算机应用基础是考试大纲,全国计算机应用技术证书考试(NIT)考试大纲(计算机应用基础Windows XP)...
  5. 操作系统:Win10系统下LocalNow和Roaming文件夹介绍
  6. 《C#与.net高级编程》——第一支柱:C#的封装
  7. Java中Map里put方法的返回值
  8. KVM-Arch-Figure
  9. 《『若水新闻』客户端开发教程》——14.代码编写(6)
  10. 测试到产品经理的进阶之路
  11. 摆脱臃肿--Unity3D安卓包减肥秘笈
  12. sql递归查询上级_递归的实际业务场景之MySQL 递归查询
  13. 旷视科技科创板IPO上会在即,毫不吝啬研发投入
  14. 五笔中比较难拆解的字
  15. 笔记 | 制作windows10装机U盘,换固态硬盘,加内存条
  16. UE4贴图自适应屏幕大小
  17. 在win10子系统ubuntu平台下使用jekyll和github pages搭建自己的静态博客网站
  18. 牛客网 18 二维数组中的查找
  19. SpringBoot重点详解--使用过滤器映射访问路径
  20. Thinkphp使用EasyWeChat支付

热门文章

  1. 英语不会读怎么办?它来教你……
  2. 第10步 (1)logback.xml日志配置(2) ftp(上传文件)服务器配置(3) idea注入和自动编译配置(4)项目提交gitee(5)fe助手和restlet client
  3. vue 字典_【开源】基于Vue的前端组件库HeyUI
  4. matlab 定义一个有自变量的方程_常微分方程:(第四章) 高阶微分方程
  5. 使用Eclipse构建Maven项目 (step-by-step)
  6. mybatis-spring 入门到实例
  7. 脚本错误和安全警报怎么解决_适用于应用程序错误的AWS警报
  8. go比java快多少_Java 11快多少?
  9. oauth 使用令牌_使用OAuth2令牌的安全REST服务
  10. 如何在Spring Boot应用程序中使用配置文件