Friday, January 22, 2016

Multiplayer Card Game using WebSockets,Java Netty Server ,Cocos2d-x-HTML5 - Part 2


Game Server Source code overview 
In this post i will try to explain how develop basic Game Server that is using WebSockets as its networking protocol .To communicate between the server and the clients.In this tutorial to keep things very simple i don't use any third party java library's .

I only will be using Netty self contained framework that comes in 1 jar .

Super  crash course on WebSockets:

  • WebSockets protocol is the most close thing to common standard between browsers , mobiles
    desktops  clients .which enables continuous open connection over TCP
  • WebSockets have build in mechanism which checks if the server supports WebSockets using
    HTTP request 
    handshake first when connecting to server
  • WebSockets is event driven , it means both sides the client and server will know whats going on . and will be notified by callbacks.
Super  crash course on Java Netty Server:
  • Netty is asynchronous TCPIP server framework developed in JAVA. asynchronous  means it is using very few threads to handle incoming traffic , and it never waits . so it is easy on the CPU
  • Netty have build in WebSocket support , no need to add third party library.
  • Netty is relatively easy to debug using powerful java eclipse IDE , 
  • Netty have proven positive record in the industry as one of the lead framework when it comes
    to handle massive traffic.
Client Server "Architecture" 

How does our simple client server will work is drawn in this simple diagram :

GameServerMain.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 public class GameServerMain {
 private final static Logger LOG = LoggerManager.GetLogger(GameServerMain.class.getName());
 public static void main(String[] args) {
   
  final ResourceBundle configurationBundle = ResourceBundle.getBundle("configuration");
  int port = Integer.valueOf(configurationBundle.getString("port"));
  WebSocketServer pWebSocketServer = new WebSocketServer(); 
  pWebSocketServer.start(port);
  LOG.info("server started");
  
 }

}
  1. Line 5: Load configuration from configuration.propeties file 
  2. Line 6: get the port to for the server to listen.
  3. Line 7 - 9: start the server . 
WebSocketServer.java 

This class is standard initialization sequence of Netty server .
It will initialize our Game Logic class :GameManager
It will set Netty to be A sync when it comes to  handling incoming requests ,
Called also NIO in java world . Non-blocking I/O.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class WebSocketServer {
  private final ChannelGroup channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
     private final EventLoopGroup group = new NioEventLoopGroup();    
     private final GameManager gameManager = new GameManager(); 
     private Channel channel;
     public ChannelFuture start(int address) {
         ServerBootstrap bootstrap  = new ServerBootstrap();
         bootstrap.group(group)
                 .channel(NioServerSocketChannel.class)
                 .childHandler(createInitializer(gameManager));
         ChannelFuture future = bootstrap.bind(new InetSocketAddress(address));
         future.syncUninterruptibly();
         channel = future.channel();
         return future;
     }

     protected ChannelInitializer<Channel> createInitializer(GameManager _gameManager) {
        return new GameServerInitializer(gameManager);
     }

     public void destroy() {
         if (channel != null) {
             channel.close();
         }
         channelGroup.close();
         group.shutdownGracefully();
     }
}

  1. Lines 3: Init Netty as Non-blocking I/O. server.
  2. Line 4: create one of the game logic objects ( more on this in Part 3 ) .
  3. Lines 6 - 14: initialization sequence of Netty.
  4. Lines 17 -18: set Netty server channel handlers.
    Channel is where the communication between the server and client pass through.
    Netty present the idea of Handlers . that means the raw data that pass through
    Will be handled on its way to the server when down , there are handlers that handler
    The data in the way back to the client .
    This is very wide subject . and it way out the scope on this tutorial .
    You can start to learn about it here :
    http://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html

GameServerInitializer.java

This class is where the Channel handlers are set up , someone them are Netty build in handlers
And some of them are Extended Class's . Netty gives us the option to manipulate the data .


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class GameServerInitializer extends ChannelInitializer<Channel> {
 private final GameManager gameManager; 
    public GameServerInitializer(GameManager _gameManager) {
     this.gameManager = _gameManager;
    }
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast("HttpServerCodec",new HttpServerCodec());
        pipeline.addLast("HttpObjectAggregator",new HttpObjectAggregator(64 * 1024));
        pipeline.addLast("WebSocketServerProtocolHandler",new WebSocketServerProtocolHandler("/ws"));        
        pipeline.addLast("TextWebSocketFrameHandler",new TextWebSocketFrameHandler(gameManager,new GameEventHandler(gameManager)));
     }
}


  1. Lines 4: we pass the GameManger object throw all the initiations of the objects .
    We need the GameManger to be Central point for our game logic. it will keep all the game states  and the players . 
  2. Lines 8 -14 :all the channel handlers that will handle the WebSocket requests and responses.
    The setup is done by the entering the handlers into Map ,
    Handlers which are extending SimpleChannelInboundHandler  are Usually handle Inbound data
    and those Handlers we are going to use . and extend .
  3. Line 10: HttpServerCodec is Netty builtin handler  to handle HTTP requests to decode and encode  them back.
  4. Line 11: HttpObjectAggregator is Netty builtin handler its job  to aggregate the fractions of
    HTTP request and only pass it to the next handler when the FULL request is arrived from the client .
  5. Line 12: WebSocketServerProtocolHandler  is Handler which is extended to handle the WebSocket http handshake and approval if to pass the incoming WebSocket request to the next handler.
  6. Line 13: TextWebSocketFrameHandler is handler which is extending Netty SimpleChannelInboundHandler class.
    this is where the actual Text from the client is accepted and manipolated by the server to handle game states  more on this when we analyze the  TextWebSocketFrameHandler .java source code.
      

We are ready to dive deeper into the game server logic in the next post :

Multiplayer Card Game using WebSockets,Java Netty Server ,Cocos2d-x-HTML5 - Part 3




No comments:

Post a Comment