Netty的簡(jiǎn)單Demo

TimeServer:

public class TimeServer {
    public void bind(int port) throws Exception {
        // 配置服務(wù)端的NIO線程組
        //用于網(wǎng)絡(luò)事件處理
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //啟動(dòng)NIO服務(wù)端的輔助啟動(dòng)類
            ServerBootstrap b = new ServerBootstrap();
            //將創(chuàng)建的channel作為ServerSocketChannel
            b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childHandler(new ChildChannelHandler());
            // 綁定端口,同步等待成功
            ChannelFuture f = b.bind(port).sync();

            // 等待服務(wù)端監(jiān)聽端口關(guān)閉
            f.channel().closeFuture().sync();
        } finally {
            // 優(yōu)雅退出诡必,釋放線程池資源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
    private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{

        @Override
        protected void initChannel(SocketChannel sc) throws Exception {
            sc.pipeline().addLast(new TimeServerHandler());
        }
    }
    
    public static void main(String[] args) throws Exception {
        int port=8080;
        if(args!=null&&args.length>0){
            try {
                port=Integer.valueOf(args[0]);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        new TimeServer().bind(port);
    }
}

TimeServerHandler(channelHandlerAdapter部分方法只有5.0.0才有):

public class TimeServerHandler extends ChannelHandlerAdapter {
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("The time server receive order : " + body);
        String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(
                System.currentTimeMillis()).toString() : "BAD ORDER";
        ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
        ctx.write(resp);
    }

    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //netty的消息不直接寫入channel,它放在緩沖數(shù)組,調(diào)用flush()才寫入
        ctx.flush();
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.close();
    }
}

TimeClient:

public class TimeClient {
    public void connect(int port, String host) throws Exception {
        // 配置客戶端NIO線程組
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        //初始化時(shí)將handler設(shè)置到ChannelPipeline
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(new TimeClientHandler());
                        }
                    });

            // 發(fā)起異步連接操作
            ChannelFuture f = b.connect(host, port).sync();

            // 當(dāng)代客戶端鏈路關(guān)閉
            f.channel().closeFuture().sync();
        } finally {
            // 優(yōu)雅退出员舵,釋放NIO線程組
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        if (args != null && args.length > 0) {
            try {
                port = Integer.valueOf(args[0]);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        new TimeClient().connect(port, "127.0.0.1");
    }
}

TimeClientHandler:

public class TimeClientHandler extends ChannelHandlerAdapter {

    private static final Logger logger = Logger
            .getLogger(TimeClientHandler.class.getName());

    private final ByteBuf firstMessage;

    /**
     * Creates a client-side handler.
     */
    public TimeClientHandler() {
        byte[] req = "QUERY TIME ORDER".getBytes();
        firstMessage = Unpooled.buffer(req.length);
        firstMessage.writeBytes(req);
    }
    //客戶端和服務(wù)端TCP鏈路建立成功后調(diào)用此方法
    public void channelActive(ChannelHandlerContext ctx) {
        //通過此方法將消息發(fā)送給服務(wù)端
        ctx.writeAndFlush(firstMessage);
    }
    //服務(wù)端返回應(yīng)答消息調(diào)用此方法
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("Now is : " + body);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 釋放資源
        logger.warning("Unexpected exception from downstream : "
                + cause.getMessage());
        ctx.close();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末个绍,一起剝皮案震驚了整個(gè)濱河市隔心,隨后出現(xiàn)的幾起案子踏兜,更是在濱河造成了極大的恐慌军拟,老刑警劉巖幸乒,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異漠秋,居然都是意外死亡笙蒙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門庆锦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捅位,“玉大人,你說我怎么就攤上這事搂抒÷淘” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵燕耿,是天一觀的道長(zhǎng)中符。 經(jīng)常有香客問我,道長(zhǎng)誉帅,這世上最難降的妖魔是什么淀散? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮蚜锨,結(jié)果婚禮上档插,老公的妹妹穿的比我還像新娘。我一直安慰自己亚再,他們只是感情好郭膛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氛悬,像睡著了一般则剃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上如捅,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天棍现,我揣著相機(jī)與錄音,去河邊找鬼镜遣。 笑死己肮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谎僻,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼娄柳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了艘绍?” 一聲冷哼從身側(cè)響起赤拒,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鞍盗,沒想到半個(gè)月后需了,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跳昼,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡般甲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹅颊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敷存。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖堪伍,靈堂內(nèi)的尸體忽然破棺而出锚烦,到底是詐尸還是另有隱情,我是刑警寧澤帝雇,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布涮俄,位于F島的核電站,受9級(jí)特大地震影響尸闸,放射性物質(zhì)發(fā)生泄漏彻亲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一吮廉、第九天 我趴在偏房一處隱蔽的房頂上張望苞尝。 院中可真熱鬧,春花似錦宦芦、人聲如沸宙址。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抡砂。三九已至,卻和暖如春恬涧,著一層夾襖步出監(jiān)牢的瞬間舀患,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工气破, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聊浅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像低匙,于是被迫代替她去往敵國(guó)和親旷痕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 最近在寫個(gè)性化推薦的論文顽冶,經(jīng)常用到Python來(lái)處理數(shù)據(jù)欺抗,被pandas和numpy中的數(shù)據(jù)選取和索引問題繞的比較...
    shuhanrainbow閱讀 4,567評(píng)論 6 19
  • 【1】7,9强重,-1绞呈,5,( ) A间景、4佃声;B、2倘要;C圾亏、-1;D封拧、-3 分析:選D志鹃,7+9=16;9+(-1)=8泽西;(...
    Alex_bingo閱讀 18,951評(píng)論 1 19
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法曹铃,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法捧杉,繼承相關(guān)的語(yǔ)法陕见,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,661評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理糠溜,服務(wù)發(fā)現(xiàn)淳玩,斷路器,智...
    卡卡羅2017閱讀 134,696評(píng)論 18 139
  • 真心覺得越長(zhǎng)大 越是辛苦 越孤獨(dú) 有的時(shí)候不知道自己這樣的堅(jiān)持為了什么 不進(jìn)則退 始終沒能找到那份安全感 那份歸屬...
    夏小朵0323閱讀 193評(píng)論 0 0