基于netty4.0+spring的游戏完整架构

之前写过一篇和本文类似的博客,不过原博客是基于netty3.x实现的,今天整理了一份基于4.0的完整系统分享给大家,希望能对大家有所帮助。 

架构细节原博客都有,请参照  http://cpjsjxy.iteye.com/blog/1587601 

propholder.xml 
Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"  
  5.     xsi:schemaLocation="   
  6.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  7.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd   
  8.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  9.     <bean id="propertyConfigurer"  
  10.         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  11.         <property name="locations">  
  12.             <list>  
  13.                 <value>config/properties/settings.properties</value>  
  14.             </list>  
  15.         </property>  
  16.     </bean>  
  17.     <bean id="serverInitializer" class="com.cp.netty.ServerInitializer"  
  18.         init-method="init">  
  19.         <property name="timeout" value="${app.channel.readtimeout}" />  
  20.         <property name="handlerDispatcher" ref="handlerDispatcher" />  
  21.         <property name="requestType" value="${app.requestType}" />  
  22.   
  23.     </bean>  
  24.   
  25.     <bean id="handlerDispatcher" class="com.cp.dispatcher.HandlerDispatcher">  
  26.         <property name="messageExecutor">  
  27.             <bean class="com.cp.domain.FiexThreadPoolExecutor"  
  28.                 destroy-method="shutdown">  
  29.                 <constructor-arg value="${app.handler.pool.corePoolSize}" />  
  30.                 <constructor-arg value="${app.handler.pool.maximumPoolSize}" />  
  31.                 <constructor-arg value="${app.handler.pool.keepAliveSecond}" />  
  32.                 <constructor-arg value="${app.handler.pool.name}" />  
  33.             </bean>  
  34.         </property>  
  35.         <property name="sleepTime" value="${app.handler.sleepTime}" />  
  36.         <property name="handlerMap" ref="gameHandlerMap" />  
  37.     </bean>  
  38.   
  39.     <bean id="gameHandlerMap" class="java.util.HashMap">  
  40.         <constructor-arg>  
  41.             <map>  
  42.                 <entry key="999">  
  43.                     <bean class="com.cp.handler.InitHandler">  
  44.                     </bean>  
  45.                 </entry>  
  46.             </map>  
  47.         </constructor-arg>  
  48.     </bean>  
  49.   
  50. </beans>  


settings.properties 
Java代码   收藏代码
  1. app.handler.pool.corePoolSize=16  
  2. app.handler.pool.maximumPoolSize=32  
  3. app.handler.pool.keepAliveSecond=300  
  4. app.handler.pool.name=gamework  
  5. app.handler.sleepTime=10  
  6. app.channel.readtimeout = 3600  
  7. #http  socket  websocket_text  websocket_binary  
  8. app.requestType=socket  



测试类 
TestClient 

Java代码   收藏代码
  1. package com.cp.test;  
  2.   
  3. import io.netty.bootstrap.Bootstrap;  
  4. import io.netty.buffer.ByteBuf;  
  5. import io.netty.buffer.Unpooled;  
  6. import io.netty.channel.ChannelFuture;  
  7. import io.netty.channel.ChannelInitializer;  
  8. import io.netty.channel.ChannelOption;  
  9. import io.netty.channel.EventLoopGroup;  
  10. import io.netty.channel.nio.NioEventLoopGroup;  
  11. import io.netty.channel.socket.SocketChannel;  
  12. import io.netty.channel.socket.nio.NioSocketChannel;  
  13. import io.netty.handler.codec.LengthFieldBasedFrameDecoder;  
  14. import io.netty.handler.codec.LengthFieldPrepender;  
  15. import io.netty.handler.codec.http.DefaultFullHttpRequest;  
  16. import io.netty.handler.codec.http.HttpHeaders;  
  17. import io.netty.handler.codec.http.HttpMethod;  
  18. import io.netty.handler.codec.http.HttpRequestEncoder;  
  19. import io.netty.handler.codec.http.HttpResponseDecoder;  
  20. import io.netty.handler.codec.http.HttpVersion;  
  21.   
  22. import java.net.URI;  
  23.   
  24. import com.cp.domain.ERequestType;  
  25.   
  26. public class TestClient {  
  27.     public void connect(String host, int port, final ERequestType requestType)  
  28.             throws Exception {  
  29.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  30.         String msg = "Are you ok?";  
  31.         if (ERequestType.SOCKET.equals(requestType)) {  
  32.             try {  
  33.                 Bootstrap b = new Bootstrap();  
  34.                 b.group(workerGroup);  
  35.   
  36.                 b.channel(NioSocketChannel.class).option(  
  37.                         ChannelOption.TCP_NODELAY, true);  
  38.                 b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);  
  39.                 b.handler(new ChannelInitializer<SocketChannel>() {  
  40.                     @Override  
  41.                     protected void initChannel(SocketChannel ch)  
  42.                             throws Exception {  
  43.                         ch.pipeline().addLast(  
  44.                                 "encode",  
  45.                                 new LengthFieldBasedFrameDecoder(  
  46.                                         Integer.MAX_VALUE, 0404));  
  47.                         ch.pipeline().addLast("decode",  
  48.                                 new LengthFieldPrepender(4));  
  49.                         ch.pipeline().addLast("handler",  
  50.                                 new ClientInboundHandler());  
  51.                     }  
  52.                 });  
  53.                 ChannelFuture f = b.connect(host, port).sync();  
  54.                 ByteBuf messageData = Unpooled.buffer();  
  55.                 messageData.writeInt(999);  
  56.                 messageData.writeInt(msg.length());  
  57.                 messageData.writeBytes(msg.getBytes());  
  58.                 f.channel().writeAndFlush(messageData).sync();  
  59.                 f.channel().closeFuture().sync();  
  60.   
  61.             } catch (Exception e) {  
  62.                 e.printStackTrace();  
  63.             }  
  64.   
  65.         } else if (ERequestType.HTTP.equals(requestType)) {  
  66.   
  67.             Bootstrap b = new Bootstrap();  
  68.             b.group(workerGroup);  
  69.             b.channel(NioSocketChannel.class);  
  70.             b.option(ChannelOption.SO_KEEPALIVE, true);  
  71.             b.handler(new ChannelInitializer<SocketChannel>() {  
  72.                 @Override  
  73.                 public void initChannel(SocketChannel ch) throws Exception {  
  74.   
  75.                     // 客户端接收到的是httpResponse响应,所以要使用HttpResponseDecoder进行解码  
  76.                     ch.pipeline().addLast(new HttpResponseDecoder());  
  77.                     // 客户端发送的是httprequest,所以要使用HttpRequestEncoder进行编码  
  78.                     ch.pipeline().addLast(new HttpRequestEncoder());  
  79.                     ch.pipeline().addLast(new ClientInboundHandler());  
  80.   
  81.                 }  
  82.             });  
  83.             ChannelFuture f = b.connect(host, port).sync();  
  84.             b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true);  
  85.             b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);  
  86.   
  87.             URI uri = new URI("http://" + host + ":" + port);  
  88.   
  89.             DefaultFullHttpRequest request = new DefaultFullHttpRequest(  
  90.                     HttpVersion.HTTP_1_1, HttpMethod.POST, uri.toASCIIString(),  
  91.                     Unpooled.wrappedBuffer(msg.getBytes("UTF-8")));  
  92.   
  93.             // 构建http请求  
  94.             request.headers().set(HttpHeaders.Names.HOST, host);  
  95.             request.headers().set(HttpHeaders.Names.CONNECTION,  
  96.                     HttpHeaders.Values.KEEP_ALIVE);  
  97.             request.headers().set(HttpHeaders.Names.CONTENT_LENGTH,  
  98.                     request.content().readableBytes());  
  99.             // 发送http请求  
  100.             f.channel().write(request);  
  101.             f.channel().flush();  
  102.             f.channel().closeFuture().sync();  
  103.         }  
  104.   
  105.         try {  
  106.         } finally {  
  107.             workerGroup.shutdownGracefully();  
  108.         }  
  109.   
  110.     }  
  111.   
  112.     public static void main(String[] args) throws Exception {  
  113.         TestClient client = new TestClient();  
  114.         client.connect("127.0.0.1"8080, ERequestType.SOCKET);  
  115.     }  
  116. }  


ClientInboundHandler 
Java代码   收藏代码
  1. package com.cp.test;  
  2.   
  3. import io.netty.buffer.ByteBuf;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6. import io.netty.handler.codec.http.HttpContent;  
  7. import io.netty.handler.codec.http.HttpHeaders;  
  8. import io.netty.handler.codec.http.HttpResponse;  
  9.   
  10. public class ClientInboundHandler extends ChannelInboundHandlerAdapter {  
  11.   
  12.     @Override  
  13.     public void channelRead(ChannelHandlerContext ctx, Object msg)  
  14.             throws Exception {  
  15.         if (msg instanceof HttpResponse) {  
  16.             HttpResponse response = (HttpResponse) msg;  
  17.             System.out.println("CONTENT_TYPE:"  
  18.                     + response.headers().get(HttpHeaders.Names.CONTENT_TYPE));  
  19.         }  
  20.         if (msg instanceof HttpContent) {  
  21.             HttpContent content = (HttpContent) msg;  
  22.             ByteBuf buf = content.content();  
  23.             System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));  
  24.             buf.release();  
  25.         }  
  26.         if (msg instanceof ByteBuf) {  
  27.             ByteBuf messageData = (ByteBuf) msg;  
  28.             int commandId = messageData.readInt();  
  29.             int length = messageData.readInt();  
  30.             byte[] c = new byte[length];  
  31.             messageData.readBytes(c);  
  32.             System.out.println("commandId:"+commandId+"\tmessage:"+new String(c));  
  33.         }  
  34.     }  
  35. }  


本测试代码已经过http、socket、websocket测试。 

鉴于很多朋友想深入交流,特提供源码demo项目下载地址: 
https://github.com/pofuchenzhou/netty-spring-game.git
分享到:   
评论
13 楼  cpjsjxy 2016-05-17  
185248148 写道
没原码啊,,,

https://github.com/pofuchenzhou/netty-spring-game
12 楼  185248148 2016-05-05  
没原码啊,,,
11 楼  cpjsjxy 2016-01-21  
roway 写道
weiluo12@126.com求源码,谢谢!!!

https://github.com/pofuchenzhou/netty-spring-game
10 楼  roway 2016-01-21  
weiluo12@126.com求源码,谢谢!!!
9 楼  zcqshine 2015-09-06  
OK 了, 基于 netty5.0的 socket 请求方式调通过了. 谢谢博主
8 楼  zcqshine 2015-09-02  
请教下博主. 反编译了你的 jar 包后, 在有 switch 的地方反编译出来的语句很奇怪, 能提供下 command 类的源码吗, 还有 ERequest 这个枚举类里的请求类型的顺序是否为SOCKET("socket"), HTTP("http"), WEBSOCKET_TEXT("websocket_text"), WEBSOCKET_BINARY("websocket_binary")
如果是按照这个顺序来的话, 那么根据反编译出来的 command 类里的 switch 语句里的逻辑好像有问题.
7 楼  zcqshine 2015-09-02  
TestClient 类84行的代码要修改, 要删掉".channel(NioSocketChannel.class)"这部分, 因为在69行处已经设置过channelFactory了, 否则运行的时候会报错:java.lang.IllegalStateException: channelFactory set already.

对了, 我用的是 netty5.0
6 楼  kenjianyin 2015-04-27  
楼主,求源码~谢谢
5 楼  ketzi 2015-01-28  
socket,websocket可以使用同一个端口不?
4 楼  cpjsjxy 2014-11-26  
web_dig 写道
2593399875@qq.com 谢谢


反编译自己看吧
3 楼  web_dig 2014-11-21  
2593399875@qq.com 谢谢
2 楼  web_dig 2014-11-21  
楼主,求源码。
1 楼  yexiaoxiao1991 2014-11-13  
                              
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值