前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty入门HelloWorld

Netty入门HelloWorld

作者头像
简单的程序员
发布2020-04-20 11:24:43
5220
发布2020-04-20 11:24:43
举报
文章被收录于专栏:奕仁专栏奕仁专栏

今天下班之后无聊,学习了一下长链接的一款非常秀的框架——netty,netty在很多?️java开发的中间件中都有很坚实的地位。于是,在下班之余我学习了一下这款优秀的框架。

从开始搭建到运行

需要准备

jdk8+、 idea maven

新建一个项目,然后分别创建server端和client端(也就是提供者和调用者) 在pom.xml内加入netty的jar包

代码语言:javascript
复制
<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
  <version>5.0.0.Alpha2</version>
</dependency>

Netty创建全部都是实现自AbstractBootstrap。客户端的是Bootstrap,服务端的则是ServerBootstrap

创建服务端

根据api提供的接口,服务端需要继承ServerBootstrap类,看一下该类的继承关系图

它是实现了抽象类,该抽象类即netty的核心之一

代码语言:javascript
复制
package org.choviwu.movie.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class ServerMain {


    public static void main(String[] args) {
	//EventLoopGroup 是在4.x版本中提出来的一个新概念。用于channel的管理。服务端需要两个。 一个是boss线程一个是worker线程。
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(eventLoopGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
					//这里是自定义的handler,用来初始化通道
                    .childHandler(new HelloServerInitializer());
            // 服务器绑定端口监听  端口10000 同步接收
            ChannelFuture future = serverBootstrap.bind(10000).sync();
            Channel channel = future.channel();
            // 监听服务器关闭监听   
            future.channel().closeFuture().sync();

        }catch (InterruptedException ex){

        }finally {
            //shutdown
            eventLoopGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

其实,我们目的就是当客户端输入消息时,服务端能够收到该消息。 DelimiterBasedFrameDecoder Netty在官方网站上提供的示例显示 有这么一个解码器可以简单的消息分割。 其次 在decoder里面我们找到了String解码编码器。着都是官网提供给我们的。

代码语言:javascript
复制
package org.choviwu.movie.netty.server;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {


    @Override
    protected void initChannel(SocketChannel ch) throws Exception {

        ChannelPipeline channelPipeline = ch.pipeline();

        channelPipeline.addLast("framer",new DelimiterBasedFrameDecoder(8500, Delimiters.lineDelimiter()));
        channelPipeline.addLast("decoder",new StringDecoder());
        channelPipeline.addLast("encoder",new StringEncoder());
        channelPipeline.addLast("handler",new HelloHandler());
        System.out.println("Socket Channel "+ ch);
    }
}

上面的三个解码和编码都是系统。 另外我们自己的Handler怎么办呢。在最后我们添加一个自己的Handler用于写自己的处理逻辑。

代码语言:javascript
复制
package org.choviwu.movie.netty.server;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.net.InetAddress;

public class HelloHandler  extends SimpleChannelInboundHandler<String> {

	//当客户端发送消息时,服务端可以从该方法上获取到该消息值
    @Override
    protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("Recieve value is : " + msg);
        ctx.writeAndFlush("成功接收Msg的值。。。"+ msg);
    }

    /**
     * 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候)
     * channelActive 和 channelInActive 在后面的内容中讲述,这里先不做详细的描述
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("RemoteAddress : " + ctx.channel().remoteAddress() + " active !");

        System.out.println("local Address "+ctx.channel().localAddress());
        // 等同于下一句   ctx.write("");  ctx.flush();
        ctx.writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n");
        //
        super.channelActive(ctx);
    }
} 

创建客户端

客户端代码相对较少,拿到消息到返回值与服务端的代码可公用

代码语言:javascript
复制
package org.choviwu.movie.netty.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.choviwu.movie.netty.server.HelloServerInitializer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ClientMain {


    public static void main(String[] args) {
	//新建一个线程 用来发送消息
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
		//客户端的父类
        Bootstrap bootstrap = new Bootstrap();
		//用NioSocketChannel来进行管理通道
		//自定义handler 用来对消息的编码等进行处理 与服务端一致
        bootstrap.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new HelloServerInitializer())
        ;
        try {
		//连接到服务端的ip和地址  并打开通道
		//在控制台上输入字符串  服务端即可监听到
            Channel channel = bootstrap.connect("127.0.0.1", 10000).sync().channel();
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            while (true){
                String line = reader.readLine();
                if(line==null){
                    continue;
                }
                /**
                 *  向服务端发送在控制台输入的文本 并用"\r\n"结尾
                 *  之所以用\r\n结尾 是因为我们在handler中添加了 DelimiterBasedFrameDecoder 帧解码。
                 *  这个解码器是一个根据\n符号位分隔符的解码器。所以每条消息的最后必须加上\n否则无法识别和解码
                 */
                channel.writeAndFlush(line+ "\r\n");
            }
        } catch (InterruptedException | IOException ex) {
            ex.printStackTrace();
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从开始搭建到运行
    • 需要准备
      • 创建服务端
        • 创建客户端
        相关产品与服务
        消息队列 TDMQ
        消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档