- Netty是异步的,事件驱动的网络应用框架。
- 传统的spring mvc:定义自己的controller实现若干个自己的方法,实现方法后指定URL映射地址,当用户请求与用户对应的地址后,流程就会将请求映射到我们编写的特定的方法上;映射完方法后,先进行一些参数的装配,校验等基本的逻辑,然后开始执行调用service相关的一些代码,完成一些真正的业务处理,处理完后,将结果返回给客户端。
- SEDA:staged event driven architect:将一个请求分为若干个阶段,每个阶段根据自己不同的情况,分为若干个线程进行分别处理。
- RMI:分布式计算系统要求运行在不同地址空间不同主机上的对象互相调用。各种分布式系统都有自己的调用协议。那么EJB组件呢?在Java里提供了完整的sockets通讯接口,但sockets要求客户端和服务端必须进行应用级协议的编码交换数据,采用sockets是非常麻烦的。一个代替Sockets的协议是RPC(Remote Procedure Call), 它抽象出了通讯接口用于过程调用,使得编程者调用一个远程过程和调用本地过程同样方便。
- 但RPC 并不支持对象,而EJB构造的是完全面向对象的分布式系统,所以,面向对象的远程调用RMI(Remote Method Invocation)成为必然选择。采用RMI,调用远程对象和调用本地对象同样方便。RMI采用JRMP(Java Remote Method Protocol)通讯协议,是构建在TCP/IP协议上的一种远程调用方法。
- RPC:远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
- RMI调用机制:RMI 采用stubs 和 skeletons 来进行远程对象(remote object)的通讯。stub 充当远程对象的客户端代理,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端代理对象stub来完成的。
- Stub:(客户端)stub 对象负责调用参数和返回值的流化(serialization)、打包解包,以及网络层的通讯过程。每个远程对象都包含一个代理对象stub,当运行在本地Java虚拟机上的程序调用运行在远程Java虚拟机上的对象方法时,它首先在本地创建该对象的代理对象stub, 然后调用代理对象上匹配的方法,代理对象会作如下工作:1)与远程对象所在的虚拟机建立连接 2)打包(marshal)参数并发送到远程虚拟机 3)等待执行结果 4)解包(unmarshal)返回值或返回的错误 5)返回调用结果给调用程序
- Skeleton:(服务端)每一个远程对象同时也包含一个skeleton对象,skeleton运行在远程对象所在的虚拟机上,接受来自stub对象的调用。当skeleton接收到来自stub对象的调用请求后,skeleton会作如下工作:1)解包stub传来的参数 2)调用远程对象匹配的方法 3)打包返回值或错误发送给stub对象
- 早期的http是基于无状态的请求-响应的模式;而使用WebSocket协议建立通信,WebSocket一旦建立好之后,服务端与客户端就会建立全双工的通信方式。特别适合于即时通信的场合。传统的则需要客户端每隔一定的时间轮询查看服务器端是否有数据更新,再将数据同步到客户端。HTTP协议包含header和body两部分,在一些即时通讯的场合,内容可能没有header长,但header是必须要的。WebSocket则允许只传数据本身而不传其他的信息。
- Maven是通过XML的方式来指定依赖包等构建项目
- Gradle是基于Groovy的特定领域语言来声明项目设置。(使用编程的方式来配置更加灵活,强大的构建能力)
- Netty可以作为一个RPC通讯的框架;Netty可以作为一个长连接的服务器,实现客户端与服务端长连接的通信;Netty可以作为HTTP的服务器,servlet容器;
- 实现第一个Netty程序:通过http://localhost:8899页面得到Hello World;(可使用命令curl “http://localhost:8899”在命令行窗口中得到返回的结果)
-
public class firstTest { //服务器启动---init中添加自定义及Netty已提供的处理器----实现自定义处理器中的回调方法 public static void main(String[] args) throws InterruptedException { // 两个事件循环组(服务端死循环) EventLoopGroup bossGroup = new NioEventLoopGroup();//不断接受客户端发来的连接 EventLoopGroup workerGroup = new NioEventLoopGroup();//处理连接,进行实际业务处理等 try{ ServerBootstrap serverBootstrap = new ServerBootstrap();//启动 serverBootstrap.group(bossGroup,workerGroup). channel(NioServerSocketChannel.class).childHandler(new serverInitializerTest()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();//设置端口号 channelFuture.channel().closeFuture().sync(); }finally {//关闭资源 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } public class httpServerHandlerTest extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { // 读取客户端发来的请求,并向客户端发送响应的方法 if(msg instanceof HttpRequest){ ByteBuf content = Unpooled.copiedBuffer("Hello world", CharsetUtil.UTF_8);//向客户端所返回的hello字符串 FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,content);//通过其提供的DefaultFullHttpResponse实现http响应 response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes()); ctx.writeAndFlush(response);//写回到客户端 } } } public class serverInitializerTest extends ChannelInitializer<SocketChannel> { //在channel被注册好以后,自动执行初始化代码 @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("httpServerCodec", new HttpServerCodec()); pipeline.addLast("httpServerHandlerTest", new httpServerHandlerTest());//使用自定义的 } }
Netty介绍及实现第一个程序Hello world
最新推荐文章于 2022-11-26 22:32:41 发布