【问题标题】:Does the concept of shared sessions exist in ASP.NET?ASP.NET 中是否存在共享会话的概念?
【发布时间】:2010-09-19 21:41:12
【问题描述】:

我正在开发一个由单个页面组成的 Web 应用程序 (ASP.NET) 游戏,在该页面上,会有一个类似于 Monopoly 的游戏板。我正在尝试确定最好的架构方法是什么。到目前为止,我确定的主要要求是:

  • 最多六个用户共享一个游戏状态对象。
  • 用户需要保持(相对)最新的游戏当前状态,即轮到谁了,活跃用户刚刚滚动了什么,其他用户有多少钱,等等。

我曾考虑将游戏状态保存在数据库中,但是当游戏状态对象(例如,缓存中)可以保持最新时,继续更新数据库似乎有点过头了。例如,流程可能是这样的:

  1. 接收来自用户的数据请求。
  2. 在数据库中查找数据。根据该数据创建对象。
  3. 验证用户是否有权根据游戏状态执行请求(即确保确实轮到他们或有足够的钱购买该财产)。
  4. 更新游戏对象。
  5. 将游戏对象写回数据库。
  6. 重复每个请求。

考虑一个服务器将同时服务多个游戏。

  1. 我考虑过使用 AJAX 向 ASP.NET 页面发出请求。
  2. 我曾考虑使用 Silverlight 对 Web 服务使用 AJAX 请求。
  3. 我曾考虑在 silverlight 中使用 WCF 双工通道。

我不知道最好的方法是什么。似乎都有自己的缺点。有没有人有这种事情的经验并愿意分享这些经验?如果我太模棱两可,请随意问自己的问题!谢谢。

更新:有人对如何根据我上面提到的三个选项实现与服务器的连接有任何建议吗?

【问题讨论】:

    标签: asp.net wcf silverlight caching duplex


    【解决方案1】:

    您可以使用 ASP.Net 缓存或应用程序状态来存储游戏对象,因为它们在用户之间共享。缓存可能是最好的地方,因为可以从中删除对象以节省内存。

    如果您使用唯一密钥将游戏对象存储在缓存中,则可以将密钥存储在每个访问者会话中,并使用它来检索共享的游戏对象。如果缓存已被清除,您将从数据库中重新创建对象。

    【讨论】:

    • 应用程序状态是否也适用于 Web 服务或仅适用于 ASP.NET 页面?
    • 如果 Web 服务托管在 Asp.Net 中,它会这样做。如果它托管在服务或应用程序中,那么我不确定......
    【解决方案2】:

    虽然更新数据库似乎有点过头了,但在扩大规模时它具有优势,因为您可以让多个 Webhead 与一个后端通信。

    一个更大的问题是您如何将游戏状态传达给客户端。虽然不时全面更新游戏状态可确保捕获任何更改并且所有客户端即使错过消息也保持同步,但游戏状态通常非常大。

    另外考虑一下,通常您希望游戏状态消息触发动画或其他显示更新以描绘动作(例如,棋子移动,在大多数情况下它不应该只出现在目的地......它应该移动全面)。

    因此,一种结合了两全其美的解决方案是保留一个数据库,该数据库收集在一个表中执行的所有操作,并具有顺序 ID。当客户端请求更新时,它可以在它知道的最后一个动作之后给出所有动作,并且客户端可以“执行”这些动作。这意味着即使请求失败,它也可以简单地重试请求,并且不会丢失任何操作。

    然后,服务器也可以根据相同的数据维护游戏状态的内部视图。它还可以拒绝非法动作并阻止它们进入游戏动作表(从而防止其他客户端被错误更新)。

    最后,因为服务器确实有“一个真实”的游戏状态,客户端可以定期检查它(这将允许您发现客户端或服务器代码中的错误)。因为服务器数据库应该被认为是主要的,所以您可以将整个游戏状态重新传输到任何获得不正确状态的客户端,因此轻微的客户端错误不会(可能)破坏体验(除了可能在下载状态时暂停)。

    【讨论】:

    • 您将其描述为每个用户都有自己独立的客户端状态。对于这样的游戏,将其实现为单个(和共享的)状态和逻辑机器要容易得多,并且可供 4 名玩家同时查看。
    • 服务器端有一个单一的状态,它强制执行规则,但是排队动作可以让系统在玩家遇到很多延迟的情况下也能顺利运行。单一共享状态的想法似乎很好,直到一个落后的玩家将每个人的体验都限制在最低的公分母上
    • 我同意,我之前考虑过实现一个历史记录,您可以告诉服务器您收到的最后一条消息,然后服务器会为您提供所有内容。
    【解决方案3】:

    您为什么不直接创建一个应用程序级对象来存储您的详细信息。有关详细信息,请参阅Application State and Global Variables in ASP.NET。您可以使用 sessionID 作为每个玩家数据的键。

    你也可以使用缓存来做同样的事情,但需要很长时间。这样做的好处是,可以在一段时间(即 6 小时或其他时间)后从缓存中刷新旧数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 2016-09-15
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多