C# 如何在Azure worker角色(AKKA.NET)中配置远程参与者配置

C# 如何在Azure worker角色(AKKA.NET)中配置远程参与者配置,c#,azure,azure-worker-roles,akka.net,C#,Azure,Azure Worker Roles,Akka.net,在过去的两天里,我一直在努力弄清楚如何将基本控制台应用程序部署到Azure worker角色中,并使其能够从某种基于客户端的应用程序(例如MVC web app)远程访问。下面的答案我首先将参与者状态包含在MVC应用程序正在与之通信的本地控制台应用程序中。我希望在Azure生态系统中部署我的应用程序,并认为在worker角色中维护状态,在应用程序服务中托管think client MVC应用程序将是最好的方法 确保您的Actor系统从您的解决方案中提取到它自己的项目中。在解决方案中创建新的工作者

在过去的两天里,我一直在努力弄清楚如何将基本控制台应用程序部署到Azure worker角色中,并使其能够从某种基于客户端的应用程序(例如MVC web app)远程访问。下面的答案

我首先将参与者状态包含在MVC应用程序正在与之通信的本地控制台应用程序中。我希望在Azure生态系统中部署我的应用程序,并认为在worker角色中维护状态,在应用程序服务中托管think client MVC应用程序将是最好的方法

确保您的Actor系统从您的解决方案中提取到它自己的项目中。在解决方案中创建新的工作者角色CloudService项目

选择工作人员角色

我将我的工作角色配置如下:

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);
        }
    }
}
<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>
为了完整起见,这里是我的客户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"
      }
    }
  }

我真的希望这能帮助其他人。我真的没有找到太多描述Akka.NET部署到Azure而不将Actor系统部署到易失性IIS应用程序服务的文档。让我知道我是否可以以任何方式改进答案。

我首先将参与者状态包含在MVC应用程序正在与之通信的本地控制台应用程序中。我希望在Azure生态系统中部署我的应用程序,并认为在worker角色中维护状态,在应用程序服务中托管think client MVC应用程序将是最好的方法

确保您的Actor系统从您的解决方案中提取到它自己的项目中。在解决方案中创建新的工作者角色CloudService项目

选择工作人员角色

我将我的工作角色配置如下:

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);
        }
    }
}
<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>
为了完整起见,这里是我的客户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"
      }
    }
  }
我真的希望这能帮助其他人。我真的没有找到太多描述Akka.NET部署到Azure而不将Actor系统部署到易失性IIS应用程序服务的文档。如果我能以任何方式改进答案,请告诉我