首先,我想为任何愚蠢的问题道歉,我还在学习网络编程。
除了出于自身兴趣之外,我从未做过太多的网络编程,而且我只使用了Java的Socket和ServerSocket类。使用这些类,我使用的范例是在服务器端有一个Java线程接受来自客户端的连接,然后将接受的Socket传递给它自己的Thread。因此,对于100个并发客户端,将有(可能)100个线程。然后,客户端和服务器可以在自己的线程上相互通信,与系统的其他组件分开。
现在进入DatagramSocket ......我刚学习TCP与UDP,所以刚刚发现了这个类。这是有道理的......你在端口上侦听数据包,并在端口/地址上发送数据包。正文包含一定数量的字节,并且是可选的(仍然可以了解最大的体型大小等)。从在线信息中,我收集到套接字侦听该端口上的任何数据包,并从数据包头派生源。
这一切都很好,而且我很乐意将这些数据包转发到池中的自己的runnables,或者他们自己的线程等等。但是,困扰我的是TCP套接字,每个线程(其中一个)上例中的100)仅接收来自适当来源的消息。使用数据报套接字,来自每个客户端的所有数据包都将转到单个线程......该线程负责分割工作。
这样的MMO游戏怎么样?说你有一个游戏服务器支持5000个玩家,每个玩家每秒发送15个数据包......那个每秒75,000个数据包,看起来很重用于处理单个线程。 (相对于5000个线程,每个线程可能每秒15个)。显然,一个线程可以根据数据包头和客户端哈希映射将数据包转发到适当的位置,但我只是觉得侦听器线程本身正在执行该逻辑。
现在可能TCP正在做类似的事情(一些数据包监听器线程将数据转发到适当的Socket),所以我真的没有失去任何东西。我想根本问题归结为......是否有可能让多个服务器线程监听同一个端口?例如,我想象一个负载均衡器,它将数据包循环到不同的DataGramSocket监听器(每个线程一个,可能3-4个线程)。然后那些监听器可以完成原始单线程的工作,即将无序数据包发送到程序中的正确位置(例如,此数据包来自端口6750上的123.456.789.123 ...让我们检查一下我们的clientMap去...好吧,发送到那个线程的数据包队列)。
我猜测答案是,只要处理所有客户端数据包的线程非常轻量级(只接收数据包,委托,重复),即使是大量流量也没有问题。
谢谢!
编辑:经过一番思考和Am_I_Helpful的评论(现在是Jamal H),我意识到你可以在机器或端口级别上抽象出来。因此,如果您有3000个玩家,您可以拥有各种负载均衡器,将该玩家引导至特定机器甚至机器上的特定端口。这样,您就可以拥有X个服务器线程,每个服务器线程都在不同端口上侦听数据包。玩家1可以命中7712端口,玩家2可以命中7713.
答案 0 :(得分:0)
首先,如果您无法访问大型团队,则不会从头开始为MMO编写所有网络代码。您将使用某种为您处理负载平衡和线程的网络框架(Netty对Java来说是一个很好的)
对于MMO,您将使用非阻塞IO(NIO),它不会将每个客户端的请求映射到其自己的线程,而是具有它想要使用的设定数量的线程(由核心数确定),以及像那样处理它
关于在单个线程上加载每个请求,有几个选项。这就是为什么MMO有多个服务器的原因,每个服务器用于游戏中的不同区域。中央服务器将为播放器提供他当前所在区域服务器的IP和端口。如果服务器功能强大,您还可以在单个服务器上接受多个端口,并且只发送不同的端口以发送给您想要平衡多个线程的负载