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 前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要 ...
随机推荐
- 使用$.getJSON()需要注意的地方
第一 JSON文件里面不能有任何注释,不能使用单引号,必须使用双引号: 第二 JSON文件名不能使用特殊字符 - ,比如 test-a.json 否则不会返回任何数据也不会报错. 使用方法: $.g ...
- Github 入门1 (下载git , 连接本地库与github仓库)
/* 本篇建立在以注册GitHub账号的前提下*/ (1) 下载 git https://www.git-scm.com // win10 可以直接红色箭头标识的 Download 2.22.0 ...
- Redis 集群(三)
为什么为有集群 在 Redis3 版本之前,每台 Redis 机器需要存储所有 Redis key ,这要求每台 Redis 机器有足够大的内存 而且只能是主节点写,从节点读,对于高并发情况下会有性能 ...
- zookeeper特性与节点说明
一.zookeeper概要.背景及作用 zookeeper产生背景: 项目从单体到分布式转变之后,将会产生多个节点之间协同的问题.如: 每天的定时任务由谁哪个节点来执行? RPC调用时的服务发现? 如 ...
- Spring 梳理-接收请求的输入(原)
Spring MVC 允许一下方式将客户端的数据传送到控制器的处理方法中 查询参数(Query Parameter) 表单参数(Form Parameter) 路径变量(Path Variable ...
- idea 环境变量设置编码
1.打开Run/Debug Configuration,选择你的tomcat 2.然后在 Server > VM options 设置为 -Dfile.encoding=UTF-8
- CentOS7 搭建php环境
1,先安装apache: yum install httpd 配置ServerName,进入httpd.conf文件: vi /etc/httpd/conf/httpd.conf 将#ServerNa ...
- Dockerfile 构建镜像
一.使用dockerfile构建镜像 基本结构: a.设置基础镜像 当前镜像继承于的基础镜像 FROM centos:latest b.设置维护者信息 没有固定格式 c.设置需要添加到容器中的文件 ...
- Docker 为非root用户授权
Docker 为非root用户授权: 当运行docker pull busybox时候,会提示sky用户无法调用docker. 那么应该把sky用户加入docker用户组,不过在添加的时候,又提示了如 ...
- 你也可以写聊天程序 - C# Socket学习1
简述 我们做软件工作的虽然每天都离不开网络,可网络协议细节却不是每个人都会接触和深入了解.我今天就来和大家一起学习下Socket,并写一个简单的聊天程序. 一些基础类 首先我们每天打开浏览器访问网页信 ...