制作游戏服务器时如何考虑Netty?

时间:2014-10-10 19:51:06

标签: java netty

我在创建GameServer时无法理解Netty的工作原理。现在,我只想在GameRoom中对2个Netty频道进行分组。下面显示了我的思考过程的代码,但是我也会在这里解释它。

当有人连接时,我想将它们与另一个玩家配对。如果没有人可用,我希望他们等到有人可以玩。一旦有人可以玩,我想把它们都放在我的游戏实例中,使用它们的频道发送输入并从服务器接收数据。

为了让一些工作变得有效,我想我只是让Game类在服务器端模拟随机输入,当它确定胜利者是谁时,它会将其发送到该特定游戏中的两个频道房间(这是试图在下面的代码中建模的内容)。

当我在创建游戏时写入Channel对象时,它们可用并且可以正常工作。但是,当我尝试从write方法访问它们时,它们不可用并显示为空指针异常。

我真的不确定如何使用netty来发挥它的潜力,如果有任何关于改进这一点的建议,请告诉我。

另外,我知道有一个基于Netty构建的Java游戏服务器,但我宁愿自己使用Netty来实现我自己的服务器作为学习体验。

全部谢谢

public class GameRoom extends Game {
    private OnlinePlayer p1;
    private OnlinePlayer p2;

    public GameRoom(Channel p1, Channel p2) {
        this.p1 = new OnlinePlayer("Tucker", p1);
        this.p2 = new OnlinePlayer("Bad Kid", p2);
        p1.writeAndFlush("Game Starting\n");
        p2.writeAndFlush("Game Starting\n");
        startGame();
    }   

    public void write(String msg) {
        System.out.println(msg);

        p1.getChannel().writeAndFlush(msg + "\n");
        p2.getChannel().writeAndFlush(msg + "\n");
    }

    @Override
    public void gameOver() {
        String msg = String.format("Winner is %s, with score of %d!", getManager().getWinner().getName(), getManager().getWinner().getScore());
        write(msg);
    }

}

public class GameServerHandler extends SimpleChannelInboundHandler<String> {
    static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    static final HashMap<SocketAddress, GameRoom> gameRoomMap = new HashMap<SocketAddress, GameRoom>();
    static final LinkedList<Channel> queue = new LinkedList<Channel>();

    @Override
    protected void messageReceived(ChannelHandlerContext ctx, String msg)
            throws Exception {
        // TODO Auto-generated method stub
        for (Channel c: channels) {
            if (c != ctx.channel()) {
                System.out.println("Writing to other channels!");
                c.writeAndFlush("[" + ctx.channel().remoteAddress() + "] " + msg + '\n');
            } else {
                c.writeAndFlush("[you] " + msg + '\n');
            }
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        Channel c = ctx.channel();
        channels.add(c);
        if (!queue.isEmpty()) {
            Channel pair = queue.pop();
            GameRoom g = new GameRoom(c, pair);
        }
        else {
            queue.add(c);
        }
        System.out.println(channels);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        System.out.println("Removing");
        Channel c = ctx.channel();
        channels.remove(c);
    }   
}

1 个答案:

答案 0 :(得分:0)

你应该在netty IO线程中写入通道上下文你的线程安全的ChunkedStream实现,其中请求到达。您还应该通过游戏线程中的此对象提供服务器更新。

请参阅stream's package文档。特别是ChunkedWriteHandler和ChunkedStream。