Java 制作游戏服务器时,如何考虑Netty?
在创建游戏服务器时,我很难理解Netty是如何工作的。现在,我只想能够在一个游戏室中组合2个网络频道。下面是我思考过程的代码,不过我也会在这里解释 当有人连接时,我想让他们与另一个玩家配对。如果没有人可用,我希望他们等到有人可用时再使用。一旦有人可以和我一起玩,我想把他们都放到我的游戏实例中,使用他们的通道从服务器发送输入和接收数据 为了让某些东西发挥作用,我想我应该让游戏类在服务器端模拟随机输入,当它确定谁是赢家时,它会将其发送到特定游戏室中的两个通道,这就是下面代码中试图建模的内容 当我在游戏创建时写入通道对象时,它们是可用的,并且可以工作。但是,当我尝试从write方法访问它们时,它们不可用,并显示为空指针异常 我真的不知道如何利用netty的潜力,如果有任何关于改进的建议,请让我知道 另外,我知道有一个Java游戏服务器构建在Netty之上,但我宁愿自己使用Netty来实现我自己的服务器作为学习体验 谢谢大家Java 制作游戏服务器时,如何考虑Netty?,java,netty,Java,Netty,在创建游戏服务器时,我很难理解Netty是如何工作的。现在,我只想能够在一个游戏室中组合2个网络频道。下面是我思考过程的代码,不过我也会在这里解释 当有人连接时,我想让他们与另一个玩家配对。如果没有人可用,我希望他们等到有人可用时再使用。一旦有人可以和我一起玩,我想把他们都放到我的游戏实例中,使用他们的通道从服务器发送输入和接收数据 为了让某些东西发挥作用,我想我应该让游戏类在服务器端模拟随机输入,当它确定谁是赢家时,它会将其发送到特定游戏室中的两个通道,这就是下面代码中试图建模的内容 当我在游
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);
}
}
您应该在请求到达的netty IO线程中将ChunkedStream的线程安全实现写入通道上下文。您还应该通过游戏线程中的此对象提供服务器更新
见文件。尤其是ChunkedWriteHandler和ChunkedStream。我想你会在不知道的情况下得到更好的响应。谢谢你的回复,我也会在那里试试。结果我不得不把GameRoom类放在它自己的线程中。。。然后它解决了我的问题。但我也会研究ChunkedStream的内容!因为我相信这将在未来为我解决问题!谢谢你的回复!是的,游戏室应该在单独的线程中。您还应该记住,通道不能直接在处理程序外部使用。您可以自由地使用响应对象进行操作-这为您提供了下游连接。对于上游链接,您可以在初始请求时将播放器ID附加到频道,并通过此ID映射来自此频道的更多消息。因此,请使用ChunkedWriteHandler正确发送数据。如何将playerID附加到频道?在通道处理程序上下文中创建HashMap?读取节。您可以使用ctx.getAttrPLAYER\u ID\u ATTR.setUUID.randomUUID设置播放器ID。在您的游戏中心,您将相应的消息路由到适当的游戏室,例如使用ConcurrentHashMap。太棒了,谢谢您的帮助。除了Netty的文档之外,是否有其他有用的参考资料可以解释您建议的工作流程?比如示例代码或者一本书什么的?再次感谢你的帮助!