• SpringBoot整合Netty


    总体来说只需要三个步骤,下面详细介绍

    第一步 创建SpringBoot工程snetty

    第二步 创建子模块也就是ModuleClient,Server,均为SpringBoot工程
    第三步 将服务器端和客户端的代码分别打成Jar包,运行Jar包。因为Netty需要客户端与服务器端两个端口才能看到效果,但是IDE的console只有一个窗口,所以需要将两个端口代码分别打成Jar包,这样再运行的话,就有两个窗口了。

    先说一下遇到的问题,具体代码在下边。

    打包运行

    因为我运行Jar包使用的是mvn exec:java这个命令,是将主函数main的参数构建在pom.xml文件中。

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <id>run-server</id>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.bihang.server.server2.EchoServer</mainClass>
                    <arguments>
                        <argument>${echo-server.port}</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    也就是说当我用mvn clean package这个命令将服务器端的代码打成Jar包之后,再运行mvn exec:java命令,此时服务器端就启动了。

    <mainClass>com.bihang.server.server2.EchoServer</mainClass>这里放的就是主函数。

    <arguments>
        <argument>${echo-server.port}</argument>
    </arguments>
    

    这里放的是主函数的参数。

    获取父级pom.xml的信息

    ${echo-server.port}这个值是从父级pom.xml中的properties中获取的,很关键的就是,在子模块Server的pom.xml中的<parent>标签中要这么写才能获得父级pom.xml中的信息。

    <parent>
        <groupId>com.bihang</groupId>
        <artifactId>snetty</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>
    

    父级中的properties:

    <properties>
        <java.version>1.8</java.version>
        <echo-server.hostname>127.0.0.1</echo-server.hostname>
        <echo-server.port>8888</echo-server.port>
    </properties>
    

    并且父级中的<packaging>标签要改成pom形式

    <packaging>pom</packaging>
    

    具体代码

    引入依赖

    <!--Netty-->
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.0.36.Final</version>
    </dependency>
    <!--Netty END-->
    <!-- 日志文件管理包 -->
    <!-- log start -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    

    服务器端和客户端都只需要两部分代码,一个是处理器程序,一个是引导程序。

    服务器端的EchoServerHandler

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelFutureListener;
    import io.netty.channel.ChannelHandler;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.util.CharsetUtil;
    
    @ChannelHandler.Sharable
    public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf in = (ByteBuf) msg;
            System.out.println(
                    "Server received: " + in.toString(CharsetUtil.UTF_8));
            ctx.write(in);
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                    .addListener(ChannelFutureListener.CLOSE);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
    

    服务器端的EchoServer

    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    import java.net.InetSocketAddress;
    
    public class EchoServer {
        private final int port;
    
        public EchoServer(int port) {
            this.port = port;
        }
    
        public static void main(String[] args) throws Exception {
            if (args.length != 1) {
                System.err.println(
                        "Usage: " + EchoServer.class.getSimpleName() +
                                " <port>");
            }
            int port = Integer.parseInt(args[0]);
            new EchoServer(port).start();
        }
    
        public void start() throws Exception {
            final EchoServerHandler serverHandler = new EchoServerHandler();
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(group)
                        .channel(NioServerSocketChannel.class)
                        .localAddress(new InetSocketAddress(port))
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                                ch.pipeline().addLast(serverHandler);
                            }
                        });
                ChannelFuture f = b.bind().sync();
                f.channel().closeFuture().sync();
            } finally {
                group.shutdownGracefully().sync();
            }
        }
    }
    

    客户端的EchoClientHandler

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.util.CharsetUtil;
    
    public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    
        //在到服务器的连接已经建立之后将被调用
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!",
                    CharsetUtil.UTF_8));
        }
        //当从服务器接收到一条消息时被调用
        @Override
        protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf in) throws Exception {
            System.out.println(
                    "Client received: " + in.toString(CharsetUtil.UTF_8));
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }
    

    客户端的EchoClient

    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    import java.net.InetSocketAddress;
    
    public class EchoClient {
        private final String host;
        private final int port;
    
        public EchoClient(String host, int port) {
            this.host = host;
            this.port = port;
        }
    
        public void start() throws Exception {
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                        .channel(NioSocketChannel.class)
                        .remoteAddress(new InetSocketAddress(host, port))
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch)
                                    throws Exception {
                                ch.pipeline().addLast(
                                        new EchoClientHandler());
                            }
                        });
                ChannelFuture f = b.connect().sync();
                f.channel().closeFuture().sync();
            } finally {
                group.shutdownGracefully().sync();
            }
        }
    
        public static void main(String[] args) throws Exception {
            if (args.length != 2) {
                System.err.println(
                        "Usage: " + EchoClient.class.getSimpleName() +
                                " <host> <port>");
                return;
            }
            String host = args[0];
            int port = Integer.parseInt(args[1]);
            new EchoClient(host, port).start();
        }
    }
    
  • 相关阅读:
    使用GetDIBts/SetDIBits高速逐点处理 from http://blog.sina.com.cn/s/blog_552ad2090100e3eu.html
    进程、应用程序域、程序集、对象上下文(转载)
    C# Data Structures
    **面试题
    你真的理解正确String某些特性了吗?
    Import data from files to SQL Server(用BULK INSERT命令导入数据详解)
    大战**面试
    海量数据面试题整理
    选择集合类
    电话面试题
  • 原文地址:https://www.cnblogs.com/bihanghang/p/10112694.html
Copyright © 2020-2023  润新知