首先,像其他人所说的那样,尽可能地将游戏逻辑分离,这样基本功能就不会过多依赖于通信基础设施。
对于通信,WCF可以处理任务。您可以让客户端向托管在IIS中的服务发送请求,进行某种身份验证,并打开一个双工通道,从中您的服务可以推送结果并通知新回合的开始。
一旦有一个客户端连接,它就等待另一个客户端。当发生这种情况时,它使用双工通道回调通知第一个客户端并等待其选择。然后它询问第二个用户,等待其响应。当响应到来时,它会将结果通知两个用户并重新启动游戏。
稍微深入实现:
您将拥有一些操作的服务(例如注册、推送决策,如果需要还有更多)。您还将定义一个回调接口,其中包含您的服务将需要推送到客户端的操作(NotifyResult、RequestDecision,同样,这些是示例)。然后,为您的客户端创建代理,将其映射到您的服务操作,并以使其公开事件的方式实现回调操作,并在服务推送消息时引发它们。
用例:
客户端A创建代理对象,调用服务器上的Register方法。服务器接收该调用,注册客户端并将回调对象保存在一个状态中。这将建立一种双向连接。这意味着(如果您使用PollingDuplexBinding,那么您可能会)从现在起,客户端A中的代理对象将向服务器发送长轮询请求,检查是否有回调消息。如果没有,则再次进行长轮询。如果有,则调用代理中回调方法,将服务器推送的数据传递给它。代理中的回调方法通常会引发事件或执行委托,具体由您选择。
客户端B连接(调用注册),与A做的一样,服务器注意到有两个客户端连接,通过保存的回调请求A的响应。这可能发生在B的注册调用处理期间,也可能在新线程中触发执行(或更好地,在ThreadPool中运行或启动一个新Task)。
客户端A将收到服务器回调请求其选择。然后可以通过UI通知用户并获取选择。向服务器发出新调用(例如PushDecision)。服务器接收到客户端A的选择后,以同样的方式向B询问。一旦它获得了两个响应,就会计算结果并将结果推送给客户端。
使用WPF的PollingDuplex双工通道的优点是,由于它使用长轮询,因此无需使用除80号端口以外的其他端口。
这并不是最终实现,只是一个小指南,为您提供一些想法,而不仅仅是提供一些模糊的建议。当然,使用WCF可能还有许多其他方法。
我们可以首先假设应用程序每次只能处理两个用户,然后,如果需要,您可以进行扩展,让您的服务保持某种状态,并使用映射表和锁定访问等方式。
关于WCF的一些想法:使用Visual Studio工具(svcutil)开始开发WCF很容易,但我不喜欢这种方法。您无法很好地了解WCF基础结构,您会被其生成代理的冗长魔术所束缚,并且您会失去灵活性,特别是在您想要使用Duplex轮询等特殊场景时。
另一种方式是手动创建您的服务和代理,这并不难,一旦您意识到可以做什么,就会变得非常有趣。在此方面,我可以给您一个建议:尽一切可能使您的代理操作使用基于任务的异步模式(您可以在
此处看到实现代理操作的不同方法)。当与新的C#
async/await关键字结合使用时,这将使您的代码更加清晰直观,并且您的UI将非常易于实现。
我可以推荐一些链接让您入门。其中一些链接已经过时,但非常有教育意义。
- 曾经有一篇关于WCF的精彩文章在这个链接上,但现在似乎已经下线了。幸运的是,我在这个链接中找到了那篇文章的内容。
- 这篇文章涵盖了您的托管选项。
- 关于WCF基础设施的主题:链接
- 关于双工服务的主题:链接 链接 链接
- 关于基于任务的异步模式的主题:链接 链接 链接