springcloud工作笔记099---springboot集成netty,进行线程管理,socket通讯

技术交流QQ群【JAVA,C++,Python,.NET,BigData,AI】:170933152 

一.依赖 


        
            io.netty
            netty-all
        

二.server端集成netty

启动类添加@ServletComponentScan

package com.hq.alp;
 
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
 
@SpringBootApplication
@ServletComponentScan//防止 @WebListener 无效
@MapperScan("com.hq.alp.mapper")
public class Application {
 
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
 
}
 

package com.hq.alp.nettys.server;
 
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
 
/**
 * Netty 服务监听器
 * @author xiangLong
 * @date 2019年5月31日 上午10:32:40
 */
@WebListener
public class NettyServerListener implements ServletContextListener {
 
    private Logger log = LoggerFactory.getLogger(NettyServerListener.class);
    
    /** 注入NettyServer */
    @Autowired
    private NettyServer nettyServer;
 
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("ServletContex初始化...");
        
        Thread thread = new Thread(new NettyServerThread());
        // 启动netty服务
        thread.start();
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
 
    }
 
    /**
     * Netty 服务启动线程
     */
    private class NettyServerThread implements Runnable {
 
        @Override
        public void run() {
            nettyServer.run();
        }
    }
 
}
 

package com.hq.alp.nettys.server;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
 
/**
 * Netty 服务端
 * @author xiangLong
 * @date 2019年5月31日 上午10:27:55
 */
@Component
public class NettyServer {
 
    /** 日志 */
    private Logger log = LoggerFactory.getLogger(NettyServer.class);
 
    /** 端口号 */
    @Value("${netty.port}")
    private int port;
 
    /**
     * 启动服务器方法
     */
    public void run() {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
            serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));
            serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);
            serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            serverBootstrap.childHandler(new NettyServerInitializer());
            // 绑定端口,开始接收进来的连接
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            log.info("netty服务启动: [port:" + port + "]");
            // 等待服务器socket关闭
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("netty服务启动异常-" + e.getMessage());
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
 
}
 

package com.hq.alp.nettys.server;
 
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;
import io.netty.util.CharsetUtil;
 
/**
 * 服务端初始化
 * @author xiangLong
 * @date 2019年5月31日 上午10:31:34
 */
public class NettyServerInitializer extends ChannelInitializer {
 
    /**
     * 初始化channel
     */
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new NettyServerHandler());
    }
 
}
 

package com.hq.alp.nettys.server;
 
import java.net.InetSocketAddress;
import java.util.Map;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import com.alibaba.fastjson.JSON;
 
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
 
/**
 * 服务端处理器
 * @author xiangLong
 * @date 2019年5月31日 上午10:31:10
 */
public class NettyServerHandler extends SimpleChannelInboundHandler {
 
    /** 日志 */
    private Logger log = LoggerFactory.getLogger(NettyServerHandler.class);
 
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        StringBuilder sb = null;
        Map result = null;
        try {
            // 报文解析处理
            sb = new StringBuilder();
            result = JSON.parseObject(msg);
 
            sb.append(result);
            sb.append("解析成功");
            sb.append("\n");
            ctx.writeAndFlush(sb);
        } catch (Exception e) {
            String errorCode = "-1\n";
            ctx.writeAndFlush(errorCode);
            log.error("报文解析失败: " + e.getMessage());
        }
    }
 
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = insocket.getAddress().getHostAddress();
        log.info("收到客户端[ip:" + clientIp + "]连接");
    }
 
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 当出现异常就关闭连接
        InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = insocket.getAddress().getHostAddress();
        log.info("客户端[ip:" + clientIp + "]连接出现异常,服务器主动关闭连接。。。");
        ctx.close();
    }
 
}
 

客户端

package com.hq.alp.nettys.client;
 
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
 
/**
 * Netty 客户端
 * @author xiangLong
 * @date 2019年5月31日 上午10:34:40
 */
public class NettyClient {
 
    /** 主机 */
    private String host;
 
    /** 端口号 */
    private int port;
 
    /**
     * 构造函数
     * @param host
     * @param port
     */
    public NettyClient(String host, int port) {
        this.host = host;
        this.port = port;
    }
 
    /**
     * 连接方法
     */
    public void connect() {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group).channel(NioSocketChannel.class);
            bootstrap.option(ChannelOption.TCP_NODELAY, true);
            // bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
            bootstrap.handler(new NettyClientInitializer());
            Channel channel = bootstrap.connect(host, port).sync().channel();
            // 发送json字符串
            String msg = "{\"name\":\"admin\",\"age\":27}\n";
            channel.writeAndFlush(msg);
            channel.closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }
    }
 
    /**
     * 测试入口
     * 
     * @param args
     */
    public static void main(String[] args) {
        String host = "127.0.0.1";
        int port = 8000;
        NettyClient nettyClient = new NettyClient(host, port);
        nettyClient.connect();
    }
 
}
 

package com.hq.alp.nettys.client;
 
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;
import io.netty.util.CharsetUtil;
 
/**
 * 客户端初始化
 * @author xiangLong
 * @date 2019年5月31日 上午10:35:54
 */
public class NettyClientInitializer extends ChannelInitializer {
 
    /**
     * 初始化channel
     */
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new NettyClientHandler());
    }
}
 

package com.hq.alp.nettys.client;
 
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
 
/**
 * 客户端处理器
 * @author xiangLong
 * @date 2019年5月31日 上午10:36:44
 */
public class NettyClientHandler extends SimpleChannelInboundHandler {
 
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("收到服务端消息: " + msg);
    }
}
 

你可能感兴趣的:(Spring,Cloud)