java游戏服务器OA现金盘平台出租开发之使用工厂模式生成netty

ava游戏服务器OA现金盘平台出租Q1157880099开发之使用工厂模式生成netty
在写netty的会发现很多东西是重复的,既然是重复的内容,我们其实可以把部分内容抽象出来写好,然后具体的内容就交到具体实现里面编写
来看下这次代码的更新情况,添加了这些内容
base
constant
ConstantValue 存放系统常量
exception
ServerErrException 服务启动错误
factory
ServerBootstrapFactory Bootstrap工厂类
ServerChannelFactory ServerChannel的工厂类
server
channel
tcp
str
TcpMessageStringHandler Channel对应的Handler处理器
TcpServerStringInitializer Channel的具体实现
pojo
ServerConfig 服务的配置内容

主要的内容是在ServerBootstrapFactory和ServerChannelFactory之中,其他的基本是为这2个类中出现的,但是需要用到的一些常量。

先看下ConstantValue,ServerErrException和ServerConfig这三个类,因为都是常量,不用太多说明,直接看代码。

ConstantValue

        

  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: ConstantValue 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 11:01 
  6.  * Description: 静态数据类 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.base.constant;  
  12.   
  13. /** 
  14.  * 〈一句话功能简述〉<br> 
  15.  * 〈静态数据类〉 
  16.  * 
  17.  * @author zhao 
  18.  * @date 2018/6/12 
  19.  * @since 1.0.0 
  20.  */  
  21. public class ConstantValue {  
  22.   public static final String CHANNEL_TYPE_NIO = "NIO";  
  23.   public static final String CHANNEL_TYPE_OIO = "OIO";  
  24.   
  25.   public static final String PROTOCOL_TYPE_HTTP = "HTTP";  
  26.   public static final String PROTOCOL_TYPE_HTTPS = "HTTPS";  
  27.   public static final String PROTOCOL_TYPE_TCP = "TCP";  
  28.   public static final String PROTOCOL_TYPE_CUSTOM = "CUSTOM";  
  29.   public static final String PROTOCOL_TYPE_WEBSOCKET = "WEBSOCKET";  
  30.   
  31.   private ConstantValue() {  
  32.   }  
  33.   
  34. }  



ServerErrException

  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: ServerErrException 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 14:36 
  6.  * Description: 服务启动错误 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.base.exception;  
  12.   
  13. /** 
  14.  * 〈一句话功能简述〉<br> 
  15.  * 〈服务启动错误〉 
  16.  * 
  17.  * @author zhao 
  18.  * @date 2018/6/12 14:36 
  19.  * @since 1.0.0 
  20.  */  
  21. public class ServerErrException extends Exception {  
  22.   private String errMsg;  
  23.   
  24.   public ServerErrException(String errMsg) {  
  25.     super(errMsg);  
  26.     this.errMsg = errMsg;  
  27.   }  
  28.   
  29.   public ServerErrException(Throwable cause) {  
  30.     super(cause);  
  31.   }  
  32. }  

ServerConfig

  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: ServerConfig 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 11:16 
  6.  * Description: 服务的配置内容 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.server.pojo;  
  12.   
  13. import org.slf4j.Logger;  
  14. import org.slf4j.LoggerFactory;  
  15.   
  16. import io.netty.channel.EventLoopGroup;  
  17.   
  18. /** 
  19.  * 〈一句话功能简述〉<br> 
  20.  * 〈服务的配置内容〉 
  21.  * 
  22.  * @author zhao 
  23.  * @date 2018/6/12 11:16 
  24.  * @since 1.0.0 
  25.  */  
  26. public class ServerConfig {  
  27.   private static final Logger logger = LoggerFactory.getLogger(ServerConfig.class);  
  28.   
  29.   private Integer port;  
  30.   private String channelType;  
  31.   private String protocolType;  
  32.   
  33.   private static ServerConfig instance = null;  
  34.   
  35.   private ServerConfig() {  
  36.   }  
  37.   
  38.   public static ServerConfig getInstance() {  
  39.     if (instance == null) {  
  40.       instance = new ServerConfig();  
  41.       instance.init();  
  42.       instance.printServerInfo();  
  43.     }  
  44.     return instance;  
  45.   }  
  46.   
  47.   private void init() {  
  48.     port = 8088;  
  49.     channelType = "NIO";  
  50.     protocolType = "TCP";  
  51.   }  
  52.   
  53.   public void printServerInfo() {  
  54.     logger.info("**************Server INFO******************");  
  55.     logger.info("protocolType  : " + protocolType);  
  56.     logger.info("port          : " + port);  
  57.     logger.info("channelType   : " + channelType);  
  58.     logger.info("**************Server INFO******************");  
  59.   }  
  60.   
  61.   public Integer getPort() {  
  62.     return port;  
  63.   }  
  64.   
  65.   public void setPort(Integer port) {  
  66.     this.port = port;  
  67.   }  
  68.   
  69.   public String getChannelType() {  
  70.     return channelType;  
  71.   }  
  72.   
  73.   public void setChannelType(String channelType) {  
  74.     this.channelType = channelType;  
  75.   }  
  76.   
  77.   public String getProtocolType() {  
  78.     return protocolType;  
  79.   }  
  80.   
  81.   public void setProtocolType(String protocolType) {  
  82.     this.protocolType = protocolType;  
  83.   }  
  84. }  


接下来看看ServerBootstrapFactory这个类,是根据我们配置的CHANNEL_TYPE(NIO,OIO)来创建不同的ServerBootstrap。

  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: ServerBootstrapFactory 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 10:56 
  6.  * Description: Bootstrap工厂类 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.base.factory;  
  12.   
  13. import com.lizhaobolg.base.constant.ConstantValue;  
  14. import com.lizhaobolg.base.exception.ServerErrException;  
  15. import com.lizhaobolg.server.pojo.ServerConfig;  
  16.   
  17. import io.netty.bootstrap.ServerBootstrap;  
  18. import io.netty.channel.EventLoopGroup;  
  19. import io.netty.channel.nio.NioEventLoopGroup;  
  20. import io.netty.channel.oio.OioEventLoopGroup;  
  21. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  22. import io.netty.channel.socket.oio.OioServerSocketChannel;  
  23.   
  24. /** 
  25.  * 〈一句话功能简述〉<br> 
  26.  * 〈Bootstrap工厂类〉 
  27.  * 
  28.  * @author zhao 
  29.  * @date 2018/6/12 
  30.  * @since 1.0.0 
  31.  */  
  32. public class ServerBootstrapFactory {  
  33.   private ServerBootstrapFactory() {  
  34.   }  
  35.   
  36.   public static ServerBootstrap createServerBootstrap() throws ServerErrException {  
  37.   
  38.     ServerBootstrap serverBootstrap = new ServerBootstrap();  
  39.     switch (ServerConfig.getInstance().getChannelType()) {  
  40.       case ConstantValue.CHANNEL_TYPE_NIO:  
  41.         EventLoopGroup bossGroup = new NioEventLoopGroup();  
  42.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  43.         serverBootstrap.group(bossGroup, workerGroup);  
  44.         serverBootstrap.channel(NioServerSocketChannel.class);  
  45.   
  46.         return serverBootstrap;  
  47.       case ConstantValue.CHANNEL_TYPE_OIO:  
  48.         serverBootstrap.group(new OioEventLoopGroup());  
  49.         serverBootstrap.channel(OioServerSocketChannel.class);  
  50.   
  51.         return serverBootstrap;  
  52.       default:  
  53.         throw new ServerErrException(  
  54.                 "Failed to create ServerBootstrap,  " +ServerConfig.getInstance().getChannelType() + " not supported!");  
  55.     }  
  56.   }  
  57. }  

然后看看ServerChannelFactory里面的逻辑,其实也就几句主逻辑,
获取配置的ip
通过ServerBootstrapFactory获取ServerBootstrap
设置ServerBootstrap的handler(通过getChildHandler()获取)
getChildHandler()通过设置的PROTOCOL_TYPE选择不同的handler
serverBootstrap绑定ip
*贯穿的其他代码是用来判断异常情况的
具体代码如下

  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: ServerChannelFactory 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 14:29 
  6.  * Description: ServerChannel的工厂类 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.base.factory;  
  12.   
  13. import com.lizhaobolg.base.constant.ConstantValue;  
  14. import com.lizhaobolg.base.exception.ServerErrException;  
  15. import com.lizhaobolg.server.channel.tcp.str.TcpServerStringInitializer;  
  16. import com.lizhaobolg.server.pojo.ServerConfig;  
  17.   
  18. import org.slf4j.Logger;  
  19. import org.slf4j.LoggerFactory;  
  20.   
  21. import io.netty.bootstrap.ServerBootstrap;  
  22. import io.netty.channel.Channel;  
  23. import io.netty.channel.ChannelFuture;  
  24. import io.netty.channel.ChannelInitializer;  
  25. import io.netty.channel.socket.SocketChannel;  
  26.   
  27. /** 
  28.  * 〈一句话功能简述〉<br> 
  29.  * 〈ServerChannel的工厂类〉 
  30.  * 
  31.  * @author zhao 
  32.  * @date 2018/6/12 14:29 
  33.  * @since 1.0.0 
  34.  */  
  35. public class ServerChannelFactory {  
  36.   private static final Logger logger = LoggerFactory.getLogger(ServerChannelFactory.class);  
  37.   
  38.   public static Channel createAcceptorChannel() throws ServerErrException {  
  39.     Integer port = ServerConfig.getInstance().getPort();  
  40.     final ServerBootstrap serverBootstrap = ServerBootstrapFactory.createServerBootstrap();  
  41.     serverBootstrap.childHandler(getChildHandler());  
  42.     //        serverBootstrap.childHandler()  
  43.     logger.info("创建Server...");  
  44.     try {  
  45.       ChannelFuture channelFuture = serverBootstrap.bind(port).sync();  
  46.       channelFuture.awaitUninterruptibly();  
  47.       if (channelFuture.isSuccess()) {  
  48.         return channelFuture.channel();  
  49.       } else {  
  50.         String errMsg = "Failed to open socket! Cannot bind to port: " + port + "!";  
  51.         logger.error(errMsg);  
  52.         throw new ServerErrException(errMsg);  
  53.       }  
  54.       //      java.net.BindException: Address already in use: bind  
  55.       //接下来就是创建一个  
  56.     } catch (Exception e) {  
  57.       logger.debug(port + "is bind");  
  58.       throw new ServerErrException(e);  
  59.     }  
  60.   }  
  61.   
  62.   private static ChannelInitializer<SocketChannel> getChildHandler() throws ServerErrException {  
  63.   
  64.     String protocolType = ServerConfig.getInstance().getProtocolType();  
  65.     if (ConstantValue.PROTOCOL_TYPE_HTTP.equals(protocolType) || ConstantValue.PROTOCOL_TYPE_HTTPS  
  66.             .equals(protocolType)) {  
  67.     } else if (ConstantValue.PROTOCOL_TYPE_TCP.equals(protocolType)) {  
  68.       return new TcpServerStringInitializer();  
  69.     } else if (ConstantValue.PROTOCOL_TYPE_WEBSOCKET.equals(protocolType)) {  
  70.     } else if (ConstantValue.PROTOCOL_TYPE_CUSTOM.equals(protocolType)) {  
  71.     } else {  
  72.     }  
  73.     String errMsg = "undefined protocol:" + protocolType + "!";  
  74.     throw new ServerErrException(errMsg);  
  75.   }  
  76. }  

最后就是写具体的handler

TcpServerStringInitializer

  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: TcpServerStringInitializer 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 15:00 
  6.  * Description: TcpServerInitializer请求处理器 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.server.channel.tcp.str;  
  12.   
  13. import io.netty.channel.ChannelInitializer;  
  14. import io.netty.channel.ChannelPipeline;  
  15. import io.netty.channel.socket.SocketChannel;  
  16. import io.netty.handler.codec.string.StringDecoder;  
  17. import io.netty.handler.codec.string.StringEncoder;  
  18.   
  19. /** 
  20.  * 〈一句话功能简述〉<br>  
  21.  * 〈TcpServerInitializer请求处理器〉 
  22.  * 
  23.  * @author zhao 
  24.  * @date 2018/6/12 15:00 
  25.  * @since 1.0.0 
  26.  */  
  27. public class TcpServerStringInitializer extends ChannelInitializer<SocketChannel> {  
  28.   
  29.   @Override  
  30.   protected void initChannel(SocketChannel ch) {  
  31.     ChannelPipeline pipeline = ch.pipeline();  
  32.     pipeline.addLast("decoder"new StringDecoder());  
  33.     pipeline.addLast("encoder"new StringEncoder());  
  34.     pipeline.addLast(new TcpMessageStringHandler());  
  35.   }  
  36.   
  37. }  


TcpMessageStringHandler
  1. /** 
  2.  * Copyright (C), 2015-2018 
  3.  * FileName: TcpMessageStringHandler 
  4.  * Author:   zhao 
  5.  * Date:     2018/6/12 15:01 
  6.  * Description: tcp消息处理 
  7.  * History: 
  8.  * <author>          <time>          <version>          <desc> 
  9.  * 作者姓名           修改时间           版本号              描述 
  10.  */  
  11. package com.lizhaobolg.server.channel.tcp.str;  
  12.   
  13. import org.slf4j.Logger;  
  14. import org.slf4j.LoggerFactory;  
  15.   
  16. import io.netty.channel.ChannelHandlerContext;  
  17. import io.netty.channel.SimpleChannelInboundHandler;  
  18.   
  19. /** 
  20.  * 〈一句话功能简述〉<br>  
  21.  * 〈tcp消息处理〉 
  22.  * 
  23.  * @author zhao 
  24.  * @date 2018/6/12 15:01 
  25.  * @since 1.0.0 
  26.  */  
  27. public class TcpMessageStringHandler extends SimpleChannelInboundHandler<String> {  
  28.   private static final Logger logger = LoggerFactory.getLogger(TcpMessageStringHandler.class);  
  29.   
  30.   @Override  
  31.   public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {  
  32.     logger.debug("异常发生", throwable);  
  33.   }  
  34.   
  35.   @Override  
  36.   public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
  37.     super.channelRead(ctx, msg);  
  38.   }  
  39.   
  40.   @Override  
  41.   protected void channelRead0(ChannelHandlerContext ctx, String msg) {  
  42.     logger.info("数据内容:data=" + msg);  
  43.     String result = "小李,我是服务器,我收到你的信息了。";  
  44.     ctx.writeAndFlush(result);  
  45.   }  
  46.   
  47.   @Override  
  48.   public void channelActive(ChannelHandlerContext ctx) throws Exception {  
  49.     logger.info("建立连接");  
  50.     super.channelActive(ctx);  
  51.   }  
  52.   
  53.   @Override  
  54.   public void channelInactive(ChannelHandlerContext ctx) throws Exception {  
  55.     logger.info("连接断开");  
  56.     super.channelInactive(ctx);  
  57.   }  
  58. }  
上面的代码在码云上 https://gitee.com/lizhaoandroid/JgServer
后续代码添加,不好阅读的话,可以查看分支netty-factory
可以加qq群一起探讨Java游戏服务器开发的相关知识 676231524




阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页