Netty:另一种Web(套接字)服务器

如今, 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arm opcode hook

/**************************************/* 作者:半斤八兩/* 博客:http://cnblogs.com/bjblcracked/* 日期:2013-09-05 11:11/**************************************只是感兴趣&#xff0c;没有其他目的。失误之处敬请诸位大侠赐教!因工作需要,最近一直在研究arm.看到论坛也…

c语言程序整数四则运算,c语言中三个整数随机的四则运算

满意答案hors10722014.01.06采纳率&#xff1a;58% 等级&#xff1a;12已帮助&#xff1a;18274人#include #include #include #define N 10 //随机出10道题目int main(){int num1, num2, num3, count0, result,resultTrue,flag;//result:用户输入结果 resultTrue:正确结果 …

带有调试器的Apache Camel Eclipse工具

大约2个月前&#xff0c; Lars Heineman在 JBoss工具堆栈中的博客中介绍了改进的Apache Camel Eclipse工具。 在即将发布的版本中&#xff0c;他们将Camel调试器与本机Eclipse调试器集成在一起&#xff0c;因此当您使用断点时&#xff0c;您将获得Eclipse调试体验&#xff0c;…

马秀丽C语言程序设计答案pdf,C语言程序设计清华大学马秀丽刘志妩科后习题9答案.doc...

C语言程序设计清华大学马秀丽刘志妩科后习题9答案习 题 9二 编程题main(){int n,*a,i,j,t0;scanf("%d",&n);for(i0;ifor(j0;jscanf("%d",ai*nj);for(i0;ifor(j0;jif (*(ai*nj)!0) t1;if (t0) printf("is xia san jiao fang zhen");else prin…

从Gradle自动将工件提升到Maven Central

快速教程&#xff0c;无需在带有Gradle Nexus Staging插件的Nexus GUI中单击即可将Gradle项目中的工件提升/发布到Maven Central。 介绍 Maven Central &#xff08;又名“中央存储库”&#xff09;&#xff08;可能&#xff09;是世界上最大的一组开源工件&#xff0c;这些工…

c语言指针自定义函数,c语言函数指针定义,指针函数和函数指针的区别

往往&#xff0c;我们一提到指针函数和函数指针的时候&#xff0c;就有很多人弄不懂。下面就由小编详细为大家介绍C语言中函数指针&#xff0c;指针函数和函数指针之间的区别。c语言指针函数定义&#xff1a;函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变…

HarmonyOS的功能及场景应用

一、基本介绍 鸿蒙HarmonyOS主要应用的设备包括智慧屏、平板、手表、智能音箱、IoT设备等。具体来说&#xff0c;鸿蒙系统是一款面向全场景(移动办公、运动健康、社交通信、媒体娱乐等)的分布式操作系统&#xff0c;能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备…

java DOM4J 读取XML

最近学习Java&#xff0c;在处理XML文档的时候&#xff0c;查阅相关资料&#xff0c;发现了DOM4J这个jre库&#xff0c;相对C#的XML处理来说&#xff0c;功能还算是跟得上 下面展示一篇我自己写的一个XML读取测试 import java.util.Iterator; import java.io.BufferedReader; i…

c语言如何实现不定参数,C语言中不定参数的实现

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼但是请注意,由於 K&R C 中并不检查参数型态&#xff0c;so 在此是用 ANSIC 来说明&#xff0c;毕竟 ANSI C 是目前所有 C Compiler 都支援的标准&#xff1b;常在网路上看到有人推荐 K&R The C Programming Language 这本书…

SX-BOX试用笔记

1.今天开始试用SX-BOX&#xff0c;我将用它来做自己平时的开发和文档的工作&#xff0c;因为我的职责是一个程序员。 1.屏幕如果支持更大的也清晰的话&#xff0c;我会感觉很舒服。 2.USB设备插入还无法识别。。。 3.现在开始安装开发工具&#xff0c;目前我打算在上面安装Adob…

c语言成绩转换绩点,如何将平时成绩转化为GPA成绩?

新东方留学生资料下载姓名手机号短信验证码图片验证码年级请选择5年级6年级7年级8年级9年级高一高二高三高三复习大一大二大三大四大五研一研二研三博一博二在职课程请选择雅思托福GREGMATSAT其他行政区请选择请选择请选择{"name":{"label":"姓名&quo…

Hibernate查询缓存如何工作

介绍 既然我已经介绍了实体和集合缓存&#xff0c;现在该研究查询缓存的工作原理了。 查询缓存与实体严格相关&#xff0c;它在搜索条件和满足该特定查询过滤器的实体之间绘制关联。 像其他Hibernate功能一样&#xff0c;查询缓存也不像人们想象的那么琐碎。 实体模型 对于我…

Javascript学习笔记1 数论

1.Javascript不用担心内存的回收与对象的销毁&#xff01; 2.Javascript有&#xff1a;infinity、NaN全局变量表示 被0整除的无穷 和 非数字。undefined和null表示 未定义 和 空&#xff0c;undefined和null可以互换&#xff0c;判别二者需用 全等 号&#xff08;不光判断值&…

C语言bcd码减法过程,bcd码的减法运算规则举例.ppt

bcd码的减法运算规则举例第1章&#xff1a;微型计算机基础 本章基本要求&#xff1a; ⑴ 单片微型计算机的含义 ⑵ 各系列单片机的特点 ⑶ 51系列单片机的概念及指标(重点) ⑷ 单片微机工业产品概念 第1章&#xff1a;微型计算机基础 电子计算机是一种能对信息进行加工处理的机…

JavaFX技巧20:有很多需要展示的地方吗? 使用画布!

JavaFX应用程序似乎有两种&#xff1a;第一种使用带有节点和CSS样式的场景图&#xff0c;第二种使用单个画布。 但是&#xff0c;将这两种方法混合使用是完全合法的。 尤其是当您的应用程序必须显示大量详细信息时&#xff0c;您很容易最终创建成千上万个节点。 即使JavaFX的整…

VirtualBox命令更改虚拟硬盘空间

主要是使用VBoxManage命令来操作第一步&#xff1a;打开CMD&#xff0c;进入到virtualbox存放虚拟机的目录中(win7 系统可以直接在文件夹空白处按住shift键右键鼠标选择[在此处打开命令窗口])&#xff0c;输入[vboxmanage list hdds]可以查看所有的虚拟机的信息&#xff0c;这里…

华为手机老是android自动升级,华为手机系统怎么升级 华为手机升级系统的两种方法...

华为手机使用的均为安卓系统&#xff0c;升级方法有多种&#xff0c;各位可以根据条件不同自行选择升级。华为手机升级系统的两种方法方法一&#xff1a;手机联网更新首先把手机联网。点击设置。向下拖动点击最后一项“关于手机”点击“系统软件更新”。点击在线升级即可。友情…

Wildfly,Apache CXF和@SchemaValidation

在过去的几天中&#xff0c;我一直在进行从JBoss 4到Wildfly 8的应用程序迁移。 该应用程序使用了不同的技术&#xff0c;但是我们这里将重点放在XML Web Services JAX-WS上 。 是的&#xff0c;我知道它们已不再流行&#xff0c;但是这些是很久以前开发的&#xff0c;因此需要…

linux网络体系架构

原创kylin_zeng:http://blog.csdn.net/kylin_fire_zeng 本文参考国嵌视频教程&#xff0c;再此感谢国嵌教育。 一、协议栈层次对比&#xff1a; 1&#xff09;网络接口层把数据链路层和物理层合并在了一起&#xff0c;提供访问物理设备的驱动程序&#xff0c;对应的网络协议主…

android 自定义弹窗diss,Android中自定义PopupWindow,动态弹窗。

我的第一篇博客&#xff0c;咱们直奔主题。先上个效果图在android中自定义PopupWindow&#xff1a;1、首先定义好你想要显示的窗口的布局文件&#xff0c;再实例化一个View对象&#xff1a;窗口布局可灵活变化&#xff0c;dialog_layout.xml代码如下&#xff1a;android:id&quo…