您的位置:首页 > 编程语言 > C#

c# 实现Actor模式的游戏服务器,参考Skynet机制

2015-11-19 00:00 585 查看
摘要: Unity,c#,Actor,Skynet,游戏服务器

####0:讨论群

qq群号:390313628 unity 4.6 版本运行

####参考
服务器代码:http://git.oschina.net/liyonghelpme/GameServerCsharp

参考文献:
http://twistedoakstudios.com/blog/Post2061_emulating-actors-in-c-with-asyncawait

http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

http://blogs.msdn.com/b/csharpfaq/archive/2010/06/18/parallel-programming-task-schedulers-
and-synchronization-context.aspx

http://weblogs.asp.net/dixin/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern

http://everydaylifein.net/netframework/task-parallel-library-taskscheduler-deadlocks-threads.html

http://blogs.msdn.com/b/ericeil/archive/2009/04/23/clr-4-0-threadpool-improvements-part-1.aspx

####基本特征
Actor模式的游戏服务器的基本特征:

每个Actor的属性都是私有的;

Actor的所有的公开的方法都是 async异步方法;

Actor所有方法的执行都需要队列化,也就是不允许多个函数在不同的线程上执行,包括Actor内部方法和对外的Async方法。

####skynet基本实现
Skynet中是通过构建一个SkynetContext, 每个Context附加有一个消息队列,当消息队列中有消息的时候,线程调度器,将这个队列调度到某个线程上去执行。每个SkynetContext根据类型可以包含一个lua虚拟机。

####c#中实现
c#中为了实现上述机制,相关的重要概念包括:Task, synchronizationcontext, Async, Await;

Task是c#中的轻量级线程,由虚拟机来调度,存在多种Task的调度器,在本服务器中我们使用 synchronizationcontext 调度器。

synchronizationcontext 是c#中一个抽象概念,用于声明一个执行领域,这个领域中的函数的执行是串行的,防止出现多个函数在多个线程上执行,造成数据访问冲突,本服务器中,每个Actor是一个同步域,Actor的所有
函数都需要在同一个synchronizationcontext下执行。

async, await 是c#中实现的协程机制,通过调用await来保存当前的async函数的上下文运行状态,以便于当等待的任务完成之后,重新启动函数的执行,使用这个特性,是为了模拟skynet中lua服务器的协程机制。

####代码详解
服务器的核心代码是Actor.cs;

Actor的_messageQueue 属性,是一个synchronizationcontext, 用于同步Actor的所有函数执行。

Actor实现了一个RunTask函数,该函数启动一个Actor内部Task,该Task运行在Actor的synchronizationcontext中。

Stop函数用于终止整个Actor的运行。

ActorSynchronizationContext.cs

实现了一个可以使用await等待的,所有函数顺序执行的同步上下文。

在PlayerActor.cs 代码中展示了如何给Actor实现一个public async 方法,首先await 到Actor的messageQueue 上下文,接着执行后续的代码。

WorldActor中,展示了如何在当前Actor的上下文下启动一个Task, 以便安全的执行Task中的代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: