一直没有写过服务器,练习一下服务器开发的流程和思想。
ChannelPipeline pipeline = ch.pipeline();
if (sslCtx != null) {
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
}
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
pipeline.addLast(new WebSocketIndexPageHandler(WEBSOCKET_PATH));
pipeline.addLast(new WebSocketFrameHandler());
通过http进行注册,webscocket登录与服务器交互。
先启动minesweep服务之后再启动gate服务
gate服务会发送一个命令号给minesweep,双方持有各自的ctx,从而实现远程调用。
gate维护与服务端的链接,如果查找不到新消息的命令号就转发给clinet的远程node;
public void processMessage(ChannelHandlerContext ctx , String msg )
{
try
{
JSONObject jo = new JSONObject(msg);
int cmdID = jo.getInt("cmdID");
MsgHander handle = null;
switch (cmdID)
{
case USER_LOGIN:
handle = new LoginHandler(ctx,msg);
break;
case ENTER_MINESWEEP:
enterGame(ENTER_MINESWEEP,ctx);
break;
case RCP:
handle = nodeToClientMsg(jo);
break;
case BACK_HALL:
handle = backHall(jo);
break;
default:
handle = clientToNodeMsg(ctx,jo);
break;
}
Worker.dispath(handle);
}
catch (JSONException e)
{
System.out.print(e.getStackTrace());
}
}
minesweep服务
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
ByteBuf[] by = new ByteBuf[]{ Unpooled.wrappedBuffer(new byte[]{0})};
pipeline.addLast("frameEncoder",new LengthFieldPrepender(4));
pipeline.addLast("encoder", new StringEncoder(Charset.forName("UTF-8")));
pipeline.addLast("frameDecoder",new LengthFieldBasedFrameDecoder(1048576,0,4,0,4));
pipeline.addLast("decoder", new StringDecoder(Charset.forName("UTF-8")));
pipeline.addLast(new ServerHandler());
}
用netty自带的编码解码器,frameEncoder 和 frameDecoder负责分包。
消息处理
public void processMessage(ChannelHandlerContext ctx , String msg )
{
try
{
JSONObject jo = new JSONObject(msg);
int cmdID = jo.getInt("cmdID");
switch (cmdID)
{
case ENTER_MINESWEEP:
enterGame(jo.getJSONObject("data"));
break;
case READY_ROOM:
readyRoom(jo.getJSONObject("data"));
break;
case KICK_PLAYER:
kickPlayer(KICKED_BY_OTHER,jo.getJSONObject("data"));
break;
case EXIT_ROOM:
kickPlayer(KICKED_BY_SELF,jo.getJSONObject("data"));
break;
case SELECT_GIRD:
selectGird(jo.getJSONObject("data"));
break;
default:
break;
}
}
catch (JSONException e)
{
System.out.print(e.getStackTrace());
}
}
客服端creator通过Notification注册命令号对应的处理。
服务器地址:https://git.oschina.net/fuatnow/PlayHigh.git
客户端地址:https://git.oschina.net/fuatnow/PlayHigh-Client.git
接下来还是应该深入图形渲染。