我必须开发一个使用大量网络请求来完成其任务的客户端/服务器游戏。
客户端和服务器都通过套接字接收多个Command
。
为了处理这些命令,我创建了一个NetworkHandler
类,它在一个单独的线程上侦听新的输入,并允许我发送新的命令。
这些“命令”实际上是异构的,并且由不同的类使用。
(例如,"client ready" command
服务器类使用Main
,而"client wants a card"
类使用Game
。
所以我创建了一个CommandDispatcher
类,它监听NetworkHandler
(Observable模式)并将不同的命令分派给正确的接收者。 (全部通过接口)
问题在于,每个想要注册为"command receiver"
的班级都需要调用CommandDispatcher
来将自己设置为听众。
因为有多个类需要这个引用,所以我想在单个类中转换CommandDispatcher
,可以在任何地方访问。
我知道Singleton和全局类都很糟糕,而且我正在隐藏依赖项并且很难测试,但我看到的唯一选择是从CommandDispatcher
类传递Main
所有其他课程。
你能帮我找到更好的解决方案吗? 谢谢。
编辑:我想澄清一下我的应用是一款基于回合制的游戏,所以我没有大量的并行请求。答案 0 :(得分:4)
这是在许多环境中多次解决的常见模式。
您需要解决的主要问题是发送到达的命令的速度。您必须确保没有命令可以阻塞系统,否则您将得到不可预测的响应时间。要做到这一点,你必须尽可能少地管理它的到来。
对此的经典解决方案是让您的网络侦听器对命令执行最少量的工作并将其交给队列。基本上你应该只是抓住到达的消息,把它放在一个队列中然后回去听。甚至不要反序列化,只需将它扔到队列中。
在队列的另一端,可以有一个或多个进程拉出命令,构造适当的对象并执行您想要的任何功能。这可能是听众应该倾听的地方。通常所有会发生的事情是将反序列化的对象发送到另一个适当的队列进行处理,这样你就可以找到一个更合适的点来监听这些队列的另一端。
网络侦听器和命令处理器通常都可以使用线程池实现。
使用Observable Singleton Class处理网络调用不好吗?
坏?不 - 但它不会经受高吞吐量。最好将网络侦听器与命令调度程序解除关联。