文档章节

Netty异步编程模型上的同步调用

秋风醉了
 秋风醉了
发布于 2014/06/20 16:47
字数 987
阅读 12197
收藏 11
点赞 0
评论 0

Netty异步编程模型上的同步调用

 

Netty异步编程模型上的同步调用

看简单的一个小程序,说明什么是同步调用:所谓的同步调用就是调用一个方法,然后返回一个结果。(这个过程一直是阻塞的,直到返回值)。

而netty中异步编程模型中不是同步调用,读写都是在handler中处理。

关于同步调用和异步调用请参考http://blog.csdn.net/dan_blog/article/details/7897852

服务器端程序

package hello.netty.lyx.com;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class HelloServer {
    public void start(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            // 注册handler
                            ch.pipeline().addLast(new HelloServerInHandler());
                        }
                    }).option(ChannelOption.SO_BACKLOG, 128);

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();

        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        HelloServer server = new HelloServer();
        server.start(9090);
    }
}
package hello.netty.lyx.com;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

// 该handler是InboundHandler类型
public class HelloServerInHandler extends ChannelInboundHandlerAdapter {
    @Override
    public boolean isSharable() {
        System.out.println("==============handler-sharable==============");
        return super.isSharable();
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel-register==============");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel-unregister==============");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel-active==============");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel-inactive==============");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        System.out.println("==============channel-read==============");

        ByteBuf result = (ByteBuf) msg;
        byte[] result1 = new byte[result.readableBytes()];
        // msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中
        result.readBytes(result1);
        String resultStr = new String(result1);
        // 接收并打印客户端的信息
        System.out.println("Client said:" + resultStr);
        // 释放资源,这行很关键
        result.release();

        // 向客户端发送消息
        String response = "I am ok!";
        // 在当前场景下,发送的数据必须转换成ByteBuf数组
        ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
        encoded.writeBytes(response.getBytes());
        ctx.writeAndFlush(encoded);
        ctx.close();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel-read-complete==============");
        ctx.flush();
    }
}

客户端程序

package hello.netty.lyx.com;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * 1、Client向Server发送消息:Are you ok?
 * 2、Server接收客户端发送的消息,并打印出来。
 * 3、Server端向客户端发送消息:I am ok!
 * 4、Client接收Server端发送的消息,并打印出来,通讯结束。
 */

public class HelloClient {

    StringBuffer message = new StringBuffer();

    public String connect(String host, int port) throws Exception {

        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
//            b.option(ChannelOption.AUTO_READ, false);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new HelloClientIntHandler(message));
                }
            });

            // Start the client.
            /**
             * await()方法:Waits for this future to be completed.
             * Waits for this future until it is done, and rethrows the cause of the failure if this future
             * failed.
             */
            ChannelFuture f = b.connect(host, port).channel().closeFuture().await();
            return message.toString();

        } finally {
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        HelloClient client = new HelloClient();
        System.out.println(">>>>>>>>>>"+client.connect("127.0.0.1", 9090).toString());
    }
}
package hello.netty.lyx.com;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;


//InboundHandler类型
public class HelloClientIntHandler extends ChannelInboundHandlerAdapter {

    public StringBuffer message;

    public HelloClientIntHandler(StringBuffer message) {
        this.message = message;
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel--register==============");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel--unregistered==============");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel--inactive==============");
    }

    // 连接成功后,向server发送消息
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("==============channel--active==============");
        String msg = "Are you ok?";
        /**
         * 分配ByteBuf
         * Return the assigned {@link io.netty.buffer.ByteBufAllocator} which will be used to allocate {@link ByteBuf}s.
         */
        ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
        encoded.writeBytes(msg.getBytes());
        ctx.write(encoded);
        Thread.sleep(10000);
        ctx.flush();
    }

    // 接收server端的消息,并打印出来
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("==============channel--read==============");
        ByteBuf result = (ByteBuf) msg;
        byte[] result1 = new byte[result.readableBytes()];
        result.readBytes(result1);
        System.out.println("Server said:" + new String(result1));
        message.append(new String(result1));
        result.release();
    }
}

同步调用体现在这里,使用awaiit方法,一直等待Future的完成。

ChannelFuture f = b.connect(host, port).channel().closeFuture().await();
return message.toString();
public static void main(String[] args) throws Exception {
    HelloClient client = new HelloClient();
    System.out.println(">>>>>>>>>>"+client.connect("127.0.0.1", 9090).toString());
}

当条用connect方法时,直接返回服务器的数据。

看运行结果,可以体会到netty的同步效果

服务器端打印:

==============handler-sharable==============

==============channel-register==============

==============channel-active==============

==============channel-read==============

Client said:Are you ok?

thread sleep end

==============channel-read-complete==============

==============channel-inactive==============

==============channel-unregister==============

客户端打印

==============channel--register==============

==============channel--active==============

==============channel--read==============

Server said:I am ok!

==============channel--inactive==============

==============channel--unregistered==============

>>>>>>>>>>I am ok!

 

Process finished with exit code 0

客户端有可能还会出现这种结果:

==============channel--register==============

==============channel--active==============

==============channel--read==============

Server said:I am ok!

>>>>>>>>>>I am ok!

==============channel--inactive==============

==============channel--unregistered==============

可以体会到同步调用的效果,虽然是在netty的异步编程模型上。

==============END==============

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 222
博文 581
码字总数 411013
作品 0
东城
程序员
Linux IO模型与Java NIO

概述 看Java NIO一篇文章的时候又看到了“异步非阻塞”这个概念,一直处于似懂非懂的状态,想解释下到底什么是异步 什么是非阻塞,感觉抓不住重点。决定仔细研究一下。 本文试图研究以下问题...

yingtju ⋅ 2017/03/19 ⋅ 0

Netty高性能架构的理解之道

Netty的简单介绍 Netty 是一个 NIO client-server(客户端服务器)框架,使用 Netty 可以快速开发网络应用,例如服务器和客户 端协议。 Netty 提供了一种新的方式来使开发网络应用程序,这种新...

烂猪皮 ⋅ 05/04 ⋅ 0

三言两语闲聊 Reactive Programming

读了这篇文章《Notes on Reactive Programming Part I: The Reactive Landscape》,写一点自己的感想。 首先,反应式编程这个概念有很多含义,可能指 React JS 代表的前端技术,可能指的是函...

编走编想 ⋅ 2016/08/11 ⋅ 0

Netty系列之Netty高性能之道

背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于J...

宇智波带土 ⋅ 2014/06/17 ⋅ 1

Netty高性能之道

背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于J...

HenrySun ⋅ 2016/04/19 ⋅ 0

Java 与 Netty 实现高性能高并发

1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于...

ljianbing ⋅ 2017/04/01 ⋅ 0

NIO技术讨论

1 2015-11-01 NIO讨论 - 并发编程网:Java NIO系列教程- infoq:Netty系列之Netty线程模型- infoq:Java NIO通信框架在电信领域的实践- 经典tcp粘包分析- Mina、Netty、Twisted一起学- 理解Jav...

乒乓狂魔 ⋅ 2015/11/05 ⋅ 1

书籍推荐:《Netty权威指南》

《Netty权威指南》是异步非阻塞通信领域的经典之作,基于最新版本Netty 5.0编写,是国内首本深入介绍Netty原理和架构的技术书籍,也是作者多年实战经验的总结和浓缩。在理论方面,讲解了Net...

ddddd8 ⋅ 2017/12/05 ⋅ 0

RPC-非阻塞通信下的同步API实现原理,以Dubbo为例

Netty在Java NIO领域基本算是独占鳌头,涉及到高性能网络通信,基本都会以Netty为底层通信框架,Dubbo 也不例外。以下将以Dubbo实现为例介绍其是如何在NIO非阻塞通信基础上实现同步通信的。 ...

echov ⋅ 01/14 ⋅ 0

Netty精粹之JAVA NIO开发需要知道的

学习Netty框架以及相关源码也有一小段时间了,恰逢今天除夕,写篇文章总结一下。Netty是个高效的JAVA NIO框架,总体框架基于异步非阻塞的设计,基于网络IO事件驱动,主要贡献在于可以让用户基...

Float_Luuu ⋅ 2016/02/07 ⋅ 3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 21分钟前 ⋅ 0

centos7 git安装

由于centos中的源仓库中git不是最新版本,需要进行源码安装。 1、查看yum仓库git信息 [root@iZm5e3d4r5i5ml889vh6esZ zh]# yum info gitLoaded plugins: fastestmirrorLoading mirror s...

xixingzhe ⋅ 30分钟前 ⋅ 0

input file 重复上传同一张图片失效的解决办法

解决办法 方法一:来回切换input[type='file']的type属性值,可以是‘text’,'button','button'....,然后再切换回来‘file’ 方法二:每次取消图片预览后,重置input[type='file']的value的...

时刻在奔跑 ⋅ 31分钟前 ⋅ 0

Mahout推荐算法API详解

前言 用Mahout来构建推荐系统,是一件既简单又困难的事情。简单是因为Mahout完整地封装了“协同过滤”算法,并实现了并行化,提供非常简单的API接口;困难是因为我们不了解算法细节,很难去根...

xiaomin0322 ⋅ 36分钟前 ⋅ 0

WampServer默认web服务器根目录位置

安装WampServer之后的web服务器根目录默认位置在WampServer安装目录下的www:

临江仙卜算子 ⋅ 37分钟前 ⋅ 0

Redux的一些手法记录

Redux Redux的基本概念见另一篇文。 这里记录一下Redux在项目中的实际操作的手法。 actions 首先定义action.js,actions的type,可以另起一个action-type.js文件。 action-type.js用来存...

LinearLaw ⋅ 38分钟前 ⋅ 0

android 手势检测(左右滑动、上下滑动)

GestureDetector类可以让我们快速的处理手势事件,如点击,滑动等。 使用GestureDetector分三步: 1. 定义GestureDetector类 2. 初始化手势类,同时设置手势监听 3. 将touch事件交给gesture...

王先森oO ⋅ 52分钟前 ⋅ 0

java 方法的执行时间监控 设置超时(Future 接口)

java 方法的执行时间监控 设置超时(Future 接口) import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor......

青峰Jun19er ⋅ 57分钟前 ⋅ 0

一名开源小白的Apache成长自述

今天收到了来自Apache Vote我成为Serviceomb项目Committer的邮件,代表自己的贡献得到了充分的肯定;除了感谢团队的给力支持,我更希望将自己的成长经历——如何践行Apache Way的心得介绍给大...

微服务框架 ⋅ 59分钟前 ⋅ 0

vim介绍、颜色显示和移动光标、一般模式下复制、剪切和粘贴

1.vim 是 vi 的升级版 vim 是带有颜色显示的 mini安装的系统,一般都不带有vim [root@aminglinux-128 ~]# yum install -y vim-enhanced已加载插件:fastestmirror, langpacksLoading mir...

oschina130111 ⋅ 59分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部