ASP.NET 中是否存在共享会话的概念?
我正在开发一个由单个页面组成的 Web 应用程序 (ASP.NET) 游戏,在该页面上会有一个类似于 Monopoly 的游戏板。 我正在尝试确定最好的架构方法是什么。 到目前为止,我确定的主要要求是:
- 最多六个用户共享一个游戏状态对象。
- 用户需要(相对)了解游戏的当前状态,即轮到谁了,活跃用户刚刚滚动了什么,每个其他用户有多少钱等等。
我考虑过保留数据库中的游戏状态,但当游戏状态对象(例如,在缓存中)可以保持最新时,不断更新数据库似乎有点过分了。 例如,流程可能如下所示:
- 接收用户的数据请求。
- 在数据库中查找数据。 从该数据创建对象。
- 验证用户是否有权根据游戏状态执行请求(即确保确实轮到他们或有足够的钱购买该财产)。
- 更新游戏对象。
- 将游戏对象写回数据库。
- 对每个请求重复此操作。
考虑到单个服务器将服务多个并发游戏。
- 我考虑过使用 AJAX 向 ASP.NET 页面发出请求。
- 我考虑过使用 AJAX 请求 Web 服务使用silverlight。
- 我考虑过在silverlight中使用WCF双工通道。
我不知道最好的方法是什么。 似乎都有其缺点。 有没有人有此类事情的经验并愿意分享这些经验? 如果我太含糊的话,请随意问自己的问题! 谢谢。
更新:有没有人对如何根据我上面提到的三个选项实现与服务器的连接有任何建议?
I am working on a web application (ASP.NET) game that would consist of a single page, and on that page, there would be a game board akin to Monopoly. I am trying to determine what the best architectural approach would be. The main requirements I have identified thus far are:
- Up to six users share a single game state object.
- The users need to keep (relatively) up to date on the current state of the game, i.e. whose turn it is, what did the active user just roll, how much money does each other user have, etc.
I have thought about keeping the game state in a database, but it seems like overkill to keep updating the database when a game state object (say, in a cache) could be kept up to date. For example, the flow might go like this:
- Receive request for data from a user.
- Look up data in database. Create object from that data.
- Verify user has permissions to perform request based on the game's state (i.e. make sure it's really their turn or have enough money to buy that property).
- Update the game object.
- Write the game object back to the database.
- Repeat for every single request.
Consider that a single server would be serving several concurrent games.
- I have thought about using AJAX to make requests to an an ASP.NET page.
- I have thought about using AJAX requests to a web service using silverlight.
- I have thought about using WCF duplex channels in silverlight.
I can't figure out what the best approach is. All seem to have their drawbacks. Does anyone out there have experience with this sort of thing and care to share those experiences? Feel free to ask your own questions if I am being too ambiguous! Thanks.
Update: Does anyone have any suggestions for how to implement this connection to the server based on the three options I mention above?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用 ASP.Net 缓存或应用程序状态来存储游戏对象,因为它们是在用户之间共享的。 缓存可能是最好的地方,因为可以从其中删除对象以节省内存。
如果您使用唯一的密钥将游戏对象存储在缓存中,则可以将该密钥存储在每个访问者会话中,并使用它来检索共享的游戏对象。 如果缓存已被清除,您将从数据库重新创建对象。
You could use the ASP.Net Cache or the Application state to store the game object since these are shared between users. The cache would probably be the best place since objects can be removed from it to save memory.
If you store the game object in cache using a unique key you can then store the key in each visitors Session and use this to retrieve the shared game object. If the cache has been cleared you will recreate the object from the database.
虽然更新数据库似乎有点大材小用,但在扩展时它具有优势,因为您可以让多个网络头与一个后端通信。
更大的问题是如何将游戏状态传达给客户端。 虽然游戏状态的不时完整更新可以确保捕获任何更改并且所有客户端即使错过消息也保持同步,但游戏状态通常非常大。
还要考虑到,通常您希望游戏状态消息触发动画或其他显示更新来描绘动作(例如,一个棋子移动,在大多数情况下它不应该只出现在目的地......它应该在棋盘上移动)。
因此,一种结合了两全其美的解决方案是保留一个数据库,该数据库收集表中执行的所有操作,并具有顺序 ID。 当客户端请求更新时,它可以给出其所知道的最后一个操作之后的所有操作,并且客户端可以“执行”这些操作。 这意味着即使请求失败,它也可以简单地重试该请求,并且不会丢失任何操作。
然后,服务器也可以根据相同的数据维护游戏状态的内部视图。 它还可以拒绝非法动作并阻止它们进入游戏动作表(从而防止其他客户端被错误更新)。
最后,由于服务器确实具有“一个真实的”游戏状态,因此客户端可以定期检查该状态(这将允许您发现客户端或服务器代码中的错误)。 由于服务器数据库应被视为主要数据库,因此您可以将整个游戏状态重新传输到任何获得错误状态的客户端,因此较小的客户端错误不会(可能)破坏体验(除了下载状态时可能会出现暂停)。
While updating a database seems like overkill, it has advantages when it comes time to scale up, as you can have multiple webheads talking to one backend.
A larger concern is how you communicate the game state to the clients. While a full update of the game state from time to time ensures that any changes are caught and all clients remain in synchronization even if they miss a message, gamestate is often quite large.
Consider as well that usually you want gamestate messages to trigger animations or other display updates to portray the action (for example, of a piece moves, it shouldn't just appear at the destination in most cases... it should move across the board).
Because of that, one solution that combines the best of both worlds is to keep a database that collects all of the actions performed in a table, with sequential IDs. When a client requests an update, it can give all the actions after the last one it knew about, and the client can "act out" the moves. This means even if an request fails, it can simply retry the request and none of the actions will be lost.
The server can then maintain an internal view of the gamestate as well, from the same data. It can also reject illegal actions and prevent them from entering the game action table (and thus prevent other clients from being incorrectly updated).
Finally, because the server does have the "one true" gamestate, the clients can periodically check against that (which will allow you to find errors in your client or server code). Because the server database should be considered the primary, you can retransmit the entire gamestate to any client that gets incorrect state, so minor client errors won't (potentially) ruin the experience (except perhaps a pause while the state is downloaded).
为什么不创建一个应用程序级对象来存储您的详细信息。 请参阅 应用程序状态和全局变量在 ASP.NET 中了解详细信息。 您可以使用 sessionID 作为每个玩家数据的密钥。
您还可以使用缓存通过长时间超时来执行相同的操作。 这样做的优点是,较旧的数据可以在一段时间(即 6 小时或其他时间)后从缓存中清除。
Why don't you just create an application level object to store your details. See Application State and Global Variables in ASP.NET for details. You can use the sessionID to act as a key for the data for each player.
You could also use the Cache to do the same thing using a long time out. This does have the advantage that older data could be flushed from the Cache after a period of time ie 6 hours or whatever.