2017-10-13 122 views

回答

2

我開始讓我的Actor狀態包含在我的MVC應用程序與之通信的本地控制檯應用程序中。我希望將自己的應用程序部署到Azure生態系統中,並且認爲將狀態維持在工作者角色之內,並在應用程序服務中託管一個思維「客戶端」MVC應用程序,這將是最好的前進方向。

確保您的Actor系統從您的解決方案中解壓縮到它自己的項目中。在解決方案中創建一個新的Worker角色CloudService項目。

Azure Cloud Service Project Make sure you select worker role 選擇Worker角色

我配置我的WorkRole如下:

public class WorkerRole : RoleEntryPoint 
{ 
    private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 
    private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false); 
    private static ActorSystem ActorSystemInstance; 
    public override void Run() 
    { 
     Trace.TraceInformation("Game.State.WorkerRole is running"); 

     try 
     { 
      this.RunAsync(this.cancellationTokenSource.Token).Wait(); 
     } 
     finally 
     { 
      this.runCompleteEvent.Set(); 
     } 
    } 

    public override bool OnStart() 
    {                     
     ActorSystemInstance = ActorSystem.Create("GameSystem");    
     // Set the maximum number of concurrent connections 
     ServicePointManager.DefaultConnectionLimit = 12; 

     // For information on handling configuration changes 
     // see the MSDN topic at https://go.microsoft.com/fwlink/?LinkId=166357. 

     bool result = base.OnStart(); 

     Trace.TraceInformation("Game.State.WorkerRole has been started"); 

     return result; 
    } 

    public override void OnStop() 
    { 
     ActorSystemInstance.Terminate(); 
     Trace.TraceInformation("Game.State.WorkerRole is stopping"); 

     this.cancellationTokenSource.Cancel(); 
     this.runCompleteEvent.WaitOne(); 

     base.OnStop(); 

     Trace.TraceInformation("Game.State.WorkerRole has stopped"); 
    } 

    private async Task RunAsync(CancellationToken cancellationToken) 
    { 
     var gameController = ActorSystemInstance.ActorOf<GameControllerActor>("GameController"); 

     while (!cancellationToken.IsCancellationRequested) 
     { 
      Trace.TraceInformation("Working"); 
      await Task.Delay(1000); 
     } 
    } 
} 

而且我HOCON文件(在app.config內)如下:

<akka> 
<hocon> 
    <![CDATA[ 
    akka { 
    loglevel = DEBUG 

    actor { 
     provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote" 
     debug { 
     receive = on 
     autoreceive = on 
     lifecycle = on 
     event-stream = on 
     unhandled = on 
     } 
    } 


    remote { 
     helios.tcp { 
     transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote" 
     transport-protocol = tcp 
     enforce-ip-family = true 
     port = xxxx //the port configured in your worker role endpoint 
     hostname = "0.0.0.0" //This is the local hostname of the worker role, using 0.0.0.0 will set the Remote actor to "listen" on all available DNS/IP addresses including the loopback (127.0.0.1) 
     pulic-hostname = "xx.xx.xx.xx" //IP Address OR DNS name, but whatever is set here is what MUST be used in the Actor Selector path on the client in order for proper "association" to occur. I did find that DNS name was required for my application as I was using SignalR as a bridge between the Actor system and the web client. 

     } 
    } 
    } 
    ]]> 
</hocon> 

我們需要在工作人員角色配置中定義我們的端點,以便我們「暴露」我們可以與外界溝通的端口。所以去你的WorkerRole設置。

Endpoint Configuration

一旦工作者角色部署,你應該能夠確認該端口是telnet'ing到服務器開放和可用通過它的IP和端口,你以前配置。

與我們的客戶設置我們ActorSelection最重要的部分是IP/DNS地址如下必須匹配與IP/DNS輔助角色

ActorReferences.GameController = 
      ActorSystem.ActorSelection("akka.tcp://[email protected]:8091/user/GameController") 
       .ResolveOne(TimeSpan.FromSeconds(3)) 
       .Result; 
內的公共主機名設置中設置的HOCON配置

爲了完整這裏是我的客戶HOCON配置:

akka { 
    loglevel = OFF 

    actor { 
     provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote" 
     debug { 
     receive = on 
     autoreceive = on 
     lifecycle = on 
     event-stream = on 
     unhandled = on 
     } 
    } 


    remote { 
     helios.tcp { 
     transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote" 
     transport-protocol = tcp 
     enforce-ip-family = true 
     port = 0 //A port will be provided for us... not important as we won't be calling into the client externally 
     public-hostname = "yoursitename.azurewebsites.net" //Remember this is simply the DNS name of the client machine 
     hostname = "127.0.0.1" 
     } 
    } 
    } 

我真的希望這可以幫助別人那裏。我沒有發現很多描述Azure的部署到Azure的文檔(沒有將Actor系統部署到易失性的IIS應用服務)。讓我知道我是否可以以任何方式改進答案。