接触Orleans 有一段时间了,之前也翻译了一系列官网文档,今天我们就来一个实际的例子,来看看到底如何用这个东西来开发项目,当然经典的也是醉人的,我们就从HelloWorld开始吧。
通过前面的知识准备我们知道Orleans 项目需要n个服务端(就是silohost),n个客户端(就是调用方),然后就是提供的actors(在Orleans 中成为grain),废话少说。
首先建立一个解决方案,叫做OrleansSamples
然后,增加一个模块解决方案,叫做HelloWorlds,在解决方案下增加两个类库Sample.Interfaces,Sample.Implements,其中Sample.Implements引用Sample.Interfaces,
这两个项目中引用Orleans的核心库,你可以手动一个一个引用进来,但还是老老实实的用nuget吧。
nuget的引用两种方式一种,通过图形化的方式,另一种通过命令的方式,命令:Install-Package Microsoft.Orleans.Core (注:在这里可以找到所需的包http://dotnet.github.io/orleans/NuGets)
记得引用完后如果在nuget里有更新就更新一下,对于新版本,可能里面有些库会没有进来,否则就会报错,反正我是这么做,做完这一切,项目结构如下:
在Sample.Interfaces中增加一个接口IUserService,并且继承接口IGrainWithIntegerKey(关于这个接口有姊妹接口,关于这些接口后续会陆续讲到)
代码如下:
namespace Sample.Interfaces { public interface IUserService:IGrainWithIntegerKey { Task<bool> Exist(string mobileNumber); } }
在Sample.Implements项目中增加实现类UserService,并且继承Grain(Grain这个基类同时也提供了相应的泛型实现Grain<>,关于他们的不同点,以及功能,后续会讲到),且实现IUserService接口
代码如下:
namespace Sample.Implements { public class UserService : Grain, IUserService { public Task<bool> Exist(string mobileNumber) { return Task.FromResult<bool>(mobileNumber=="18612478956"); } } }
好了到此为止,我们已经开发好actor虽然简单,接下来我们接着增加服务启动寄宿项(关于寄宿项,可以是控制台、windows服务、winfrom、asp.net ),这里我们采用控制台,下面我们创建一个服务控制台应用程序(Server)
引用上面创建两个项目:Sample.Implements、Sample.Interfaces。(注:其实这两个项目不一定要引用进来,只要在生成项目的目录下存在他们的编译好的dll即可,silo用来自动加载启动这个他们)
引用orleans项目中服务端的类库(使用nuget命令:Install-Package Microsoft.Orleans.Server)
项目结构如下:
代码如下:
namespace Server { class Program { static void Main(string[] args) { using (var host = new SiloHost("Default")) { host.InitializeOrleansSilo(); host.StartOrleansSilo(); Console.WriteLine("启动成功!"); Console.ReadLine(); host.StopOrleansSilo(); } } } }
好一切准备就绪,我们F5吧,
当你看到这得时候是不是觉得成功了,真的成功了吗,不一定吧!
哦对了怎么没看到日志呢,好我们在项目目录下看看日志:
果然有日志文件,一看文件名称,直接告诉我们发生错误了,好让我们打开看看吧。
从发生的异常看出,好像少了一个配置文件,在orleans 服务启动时,需要一个配置文件,这个配置文件可以是OrleansConfiguration.xml或者orleans.config或者orleans.config.xml
好知道原因了,知道该怎么做了吧,在server根目录下创建一个xml文件OrleansConfiguration.xml,将该文件的属性“复制到输出目录”值更改为"如果较新则复制"
该文件中填充配置内容,如下(详细配置请看配置一节,此处不解释)
<?xml version="1.0" encoding="utf-8" ?> <OrleansConfiguration xmlns="urn:orleans"> <Globals> <StorageProviders> <Provider Type="Orleans.Storage.MemoryStorage" Name="MemoryStore" /> <Provider Type="Orleans.Storage.MemoryStorage" Name="Default" /> <!--<Provider Type="Orleans.Storage.AzureTableStorage" Name="AzureStore"/>--> </StorageProviders> <SeedNode Address="localhost" Port="22222"/> <Messaging ResponseTimeout="30s"/> </Globals> <Defaults> <Networking Address="localhost" Port="22222"/> <ProxyingGateway Address="localhost" Port="40000" /> <Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="{0}-{1}.log" PropagateActivityId="false" BulkMessageLimit="1000"> <TraceLevelOverride LogPrefix="Application" TraceLevel="Info" /> <!-- <TraceLevelOverride LogPrefix="Runtime.Dispatcher" TraceLevel="Verbose" /> <TraceLevelOverride LogPrefix="AssemblyLoader.Silo" TraceLevel="Warning" /> --> </Tracing> <Statistics MetricsTableWriteInterval="30s" PerfCounterWriteInterval="30s" LogWriteInterval="300s" WriteLogStatisticsToTable="true" StatisticsCollectionLevel="Info"/> </Defaults> </OrleansConfiguration>