JAVA netty 简单使用
实现一个功能,客户端和服务器 轮流对一个数加+1
服务器
public class Server {
public static void main(String[] args) {
NioEventLoopGroup boss=new NioEventLoopGroup(1);
NioEventLoopGroup worker=new NioEventLoopGroup(3);
try {
final ServerBootstrap server=new ServerBootstrap();
server.group(boss,worker).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ServerHandler());
}
});
ChannelFuture future = server.bind(8881).sync();
future.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}
finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
服务器handler
netty ChannelHandler 类似 spring mvc的filter,使用的是责任链模式,可以对客户端传来的数据进行层层解析,解码等操作。
在没有任何特殊操作下,默认传递在责任中的对象是ByteBuf
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//msg 其实就是个ByteBuf 对象
ByteBuf buf=(ByteBuf) msg;
int i = buf.readInt();
System.out.println("服务器收到客户端消息"+ctx.channel().remoteAddress()+" "+i);
ByteBuf newbuf=ctx.alloc().buffer(1024);
newbuf.writeInt(i+1);
ctx.writeAndFlush(newbuf);
buf.release();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
客户端
public class Client {
public static void main(String[] args) {
NioEventLoopGroup boss=new NioEventLoopGroup(1);
try {
final Bootstrap client=new Bootstrap();
client.group(boss).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ClientHandler());
}
});
ChannelFuture future = client.connect("127.0.0.1",8881).sync();
future.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}
finally {
boss.shutdownGracefully();
}
}
}
客户端handlr
public class ClientHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf=(ByteBuf)msg;
int i=buf.readInt();
System.out.println("客服端收到服务器"+ctx.channel().remoteAddress()+"---> "+i);
Thread.sleep(2000);
ByteBuf newbuf = ctx.alloc().buffer(1024);
newbuf.writeInt(i+1);
ctx.writeAndFlush(newbuf);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接服务器成功");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf buffer = ctx.alloc().buffer(1024);
buffer.writeInt(1);
ctx.writeAndFlush(buffer);
}
}
一开始很疑惑,channelRead0(ChannelHandlerContext ctx, Object msg) 方法里的msg 到底是个什么对象?
在添加其它handler之后,比如一个StringDecode,netty会自动的把ByteBuf里的字节转String,并传递在Object对象中。这是Object就是一个String。
翻了下源码,还是很清晰的
在ChannelHandlerContext 接口中有一个fireChannelRead 方法,这个方法的解释如下
> ChannelHandlerContext fireChannelRead(java.lang.Object msg)
Description copied from interface: ChannelInboundInvoker
A Channel received a message. This will result in having the ChannelInboundHandler.channelRead(ChannelHandlerContext, Object) method called of the next ChannelInboundHandler contained in the ChannelPipeline of the Channel.
Specified by:
fireChannelRead in interface ChannelInboundInvoker
简单来就是会调用handler 责任链的下一个处理类。同过fireChannelRead方法,可以给下一个责任链传递一个对象msg,这个msg会传递到下一个处理类的 ChannelRead方法上。例如,StringDecode把ByteBuf转为一个String对象msg,在调用fireChannelRead(msg),就把这个String传到下一个handler去了。
channelRead0也是同样的意思
netty是基于nio的框架,要是理解了nio,其实操作起来也不是很费劲。
JAVA netty 简单使用的更多相关文章
- Netty——简单创建服务器、客户端通讯
Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用.Netty相当简化和流线化了网络应用的编程开发过程 ...
- Java实现简单的RPC框架(美团面试)
一.RPC简介 RPC,全称为Remote Procedure Call,即远程过程调用,它是一个计算机通信协议.它允许像调用本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用) ...
- 学习 java netty (一) -- java nio
前言:近期在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,事实上也算比較早的了.主要引入非堵塞io和io多路复用.内部基于reactor模式 ...
- Java实现简单RPC框架(转)
一.RPC简介 RPC,全称Remote Procedure Call, 即远程过程调用,它是一个计算机通信协议.它允许像本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用).H ...
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...
- Java实现简单版SVM
Java实现简单版SVM 近期的图像分类工作要用到latent svm,为了更加深入了解svm,自己动手实现一个简单版的. 之所以说是简单版,由于没实用到拉格朗日,对偶,核函数等等.而 ...
- java实现简单的单点登录
java实现简单的单点登录 摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当中.本文从业务的角度分析了单点登录的需求和应用领域:从技术本身的角度分析了单点登录技术的内部机制和实现 ...
- Java自定义简单标签
Java自定义简单标签可以方便的在页面输出信息,并且对于权限的控制,和对于Jsp标签和servlet代码的分离有着很好的作用. 下面将以权限的控制为例自定义一个标签: 一.标签类型 <wxt: ...
- 主题:Java WebService 简单实例
链接地址:主题:Java WebService 简单实例 http://www.iteye.com/topic/1135747 前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要 ...
随机推荐
- Codeforces Numbers 题解
这题只需要会10转P进制就行了. PS:答案需要约分,可以直接用c++自带函数__gcd(x,y). 洛谷网址 Codeforces网址 Code(C++): #include<bits/std ...
- [AspNetCore 3.0] 在RazorPages/MVC 中使用 Blazor (Razor组件)
开发环境 Vs2019 16.3.1 dotnetcore 3.0 一.开始 新建webapp项目 dotnet new webapp -o projectname 或Vs 中新建项目选择 Web应用 ...
- Spring MVC-从零开始-文件上传(未完待续)
Spring MVC-从零开始-文件上传(未完待续)
- Shell之Xargs命令
目录 Shell之Xargs命令 参考 xargs命令简介 xargs命令格式 xargs实例说明 Shell之Xargs命令
- MySql一个生产死锁案例分析
接到上级一个生产环境MySQL死锁日志信息文件,需要找出原因并解决问题.我将死锁日志部分贴出如下: 在mysql中使用命令:SHOW ENGINE INNODB STATUS;总能获取到最近一些问题信 ...
- RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的?
目录 RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 前言 项目结构 rocketmq-client 模块 DefaultMQProducerTest Roc ...
- Spark 学习笔记之 Streaming Window
Streaming Window: 上图意思:每隔2秒统计前3秒的数据 slideDuration: 2 windowDuration: 3 例子: import org.apache.kafka.c ...
- ELK日志分析系统(3)-logstash数据处理
1. 概述 logspout收集数据以后,就会把数据发送给logstash进行处理,本文主要讲解logstash的input, filter, output处理 2. input 数据的输入处理 支持 ...
- mobaxterm使用手册
Mobaxterm V14使用手册 文章出处 https://blog.51cto.com/937761/2372598 简介 MobaXterm 一款Windows系统下全功能终端软件.以下将 ...
- docker镜像制作必备技能
正文 使用过docker的都知道dockerfile,其用于定义制作镜像的流程,由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像.可参考往期文章学习:docker基础知识整理 ...