springboot整合netty的实现方法
                                            之前花了几天去研究怎么使用netty做一个网关服务器,虽然最后还是没能用上我做的网关,但是呢netty是会用了,总结一下netty和spring boot整合。感觉不用spring boot都不会写代码了。哈哈哈
专注于为中小企业提供网站设计制作、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业西和免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
在pom文件中添加相关的依赖,这里主要的就是netty的依赖,spring boot的相关依赖本文不提
io.netty netty-all 4.1.19.Final SpringBoot-Netty SpringBoot-Netty 1.0-SNAPSHOT 
在application.yml文件中配置
#不能用localhost,否则启动报异常:Unresolved address #tcp监听的端口 tcp: port: 8090 # bossGroup的线程数 boss: thread: count: 2 # worker的线程数 worker: thread: count: 2 #是否使用长连接 so: keepalive: true backlog: 100
3.编写NettyConfig netty的配置。
package com.advsun.netty.config;
import com.advsun.netty.handlers.StringProtocolInitalizer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
 * @author 杨红星
 * @version 1.0.0
 */
@Configuration
public class NettyConfig {
  
  //读取yml中配置 
  @Value("${boss.thread.count}")
  private int bossCount;
  @Value("${worker.thread.count}")
  private int workerCount;
  @Value("${tcp.port}")
  private int tcpPort;
  @Value("${so.keepalive}")
  private boolean keepAlive;
  @Value("${so.backlog}")
  private int backlog;
  @Autowired
  @Qualifier("springProtocolInitializer")
  private StringProtocolInitalizer protocolInitalizer;
//bootstrap配置
  @SuppressWarnings("unchecked")
  @Bean(name = "serverBootstrap")
  public ServerBootstrap bootstrap() {
    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup(), workerGroup())
        .channel(NioServerSocketChannel.class)
        .childHandler(protocolInitalizer);
    Map, Object> tcpChannelOptions = tcpChannelOptions();
    Set> keySet = tcpChannelOptions.keySet();
    for (@SuppressWarnings("rawtypes")
        ChannelOption option : keySet) {
      b.option(option, tcpChannelOptions.get(option));
    }
    return b;
  }
  @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
  public NioEventLoopGroup bossGroup() {
    return new NioEventLoopGroup(bossCount);
  }
  @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully")
  public NioEventLoopGroup workerGroup() {
    return new NioEventLoopGroup(workerCount);
  }
  @Bean(name = "tcpSocketAddress")
  public InetSocketAddress tcpPort() {
    return new InetSocketAddress(tcpPort);
  }
  @Bean(name = "tcpChannelOptions")
  public Map, Object> tcpChannelOptions() {
    Map, Object> options = new HashMap, Object>();
    options.put(ChannelOption.SO_KEEPALIVE, keepAlive);
    options.put(ChannelOption.SO_BACKLOG, backlog);
    return options;
  }
  @Bean(name = "stringEncoder")
  public StringEncoder stringEncoder() {
    return new StringEncoder();
  }
  @Bean(name = "stringDecoder")
  public StringDecoder stringDecoder() {
    return new StringDecoder();
  }
  /**
   * Necessary to make the Value annotations work.
   *
   * @return
   */
  @Bean
  public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
  }
}
     4.初始化的相关配置
package com.advsun.netty.handlers;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/**
 * @author 杨红星
 * @version 1.0.0
 */
@Component
@Qualifier("springProtocolInitializer")
public class StringProtocolInitalizer extends ChannelInitializer {
  @Autowired
  StringDecoder stringDecoder;
  @Autowired
  StringEncoder stringEncoder;
  @Autowired
  ServerHandler serverHandler;
  @Override
  protected void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    pipeline.addLast("decoder", stringDecoder);
    pipeline.addLast("handler", serverHandler);
    pipeline.addLast("encoder", stringEncoder);
  }
  public StringDecoder getStringDecoder() {
    return stringDecoder;
  }
  public void setStringDecoder(StringDecoder stringDecoder) {
    this.stringDecoder = stringDecoder;
  }
  public StringEncoder getStringEncoder() {
    return stringEncoder;
  }
  public void setStringEncoder(StringEncoder stringEncoder) {
    this.stringEncoder = stringEncoder;
  }
  public ServerHandler getServerHandler() {
    return serverHandler;
  }
  public void setServerHandler(ServerHandler serverHandler) {
    this.serverHandler = serverHandler;
  }
} 5.tcp服务的配置
package com.advsun.netty.config;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;
/**
 * @author 杨红星
 * @version 1.0.0
 */
@Component
public class TCPServer {
  @Autowired
  @Qualifier("serverBootstrap")
  private ServerBootstrap b;
  @Autowired
  @Qualifier("tcpSocketAddress")
  private InetSocketAddress tcpPort;
  private ChannelFuture serverChannelFuture;
  @PostConstruct
  public void start() throws Exception {
    System.out.println("Starting server at " + tcpPort);
    serverChannelFuture = b.bind(tcpPort).sync();
  }
  @PreDestroy
  public void stop() throws Exception {
    serverChannelFuture.channel().closeFuture().sync();
  }
  public ServerBootstrap getB() {
    return b;
  }
  public void setB(ServerBootstrap b) {
    this.b = b;
  }
  public InetSocketAddress getTcpPort() {
    return tcpPort;
  }
  public void setTcpPort(InetSocketAddress tcpPort) {
    this.tcpPort = tcpPort;
  }
}6.serverHandler配置这里是实现业务逻辑的地方
package com.advsun.netty.handlers;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
/**
 * @author 杨红星
 * @version 1.0.0
 */
@Component
@Qualifier("serverHandler")
@ChannelHandler.Sharable
public class ServerHandler extends SimpleChannelInboundHandler {
  private static final Logger log = LoggerFactory.getLogger(ServerHandler.class);
  @Override
  public void channelRead0(ChannelHandlerContext ctx, String msg)
      throws Exception {
    log.info("client msg:"+msg);
    String clientIdToLong= ctx.channel().id().asLongText();
    log.info("client long id:"+clientIdToLong);
    String clientIdToShort= ctx.channel().id().asShortText();
    log.info("client short id:"+clientIdToShort);
    if(msg.indexOf("bye")!=-1){
      //close
      ctx.channel().close();
    }else{
      //send to client
      ctx.channel().writeAndFlush("Yoru msg is:"+msg);
    }
  }
  @Override
  public void channelActive(ChannelHandlerContext ctx) throws Exception {
    log.info("RamoteAddress : " + ctx.channel().remoteAddress() + " active !");
    ctx.channel().writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n");
    super.channelActive(ctx);
  }
  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    cause.printStackTrace();
    ctx.close();
  }
  @Override
  public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    log.info("\nChannel is disconnected");
    super.channelInactive(ctx);
  }
}
 这里的 channelRead0(ChannelHandlerContext ctx, String msg)当客户机有消息发送过来时会调用这个方法,这个方法的名字叫的是真的差,所以netty5.0之后取消了这个名字, 5.0之后叫messageReceived。官方都说这名字叫的傻逼
channelRead0() → messageReceived() I know. It was a silly mistake. If you are using SimpleChannelInboundHandler, you have to rename channelRead0() to messageReceived().
最后在贴一张自己在看netty实战时候画的思维导图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。
网站名称:springboot整合netty的实现方法
网站路径:http://www.cqwzjz.cn/article/ijpihg.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 