工作者角色和Web角色之间的Azure通信

Mir*_*ano 9 c# azure azure-worker-roles azure-web-roles

嗨,我正在建立一个云服务,目前有一个网络和一个工人角色.我想要的工作流程是:浏览器调用web角色上的webApi控制器,该角色将消息发送到队列(或服务总线),然后由工作角色处理.到现在为止还挺好.现在,当worker角色完成处理消息时,我想在web角色上调用一个方法,然后谁将向浏览器发出处理已完成的信号(通过SignalR).如果这不是一个正确的问题,请原谅我,因为这更像是一个"最佳实践"问题,而不是一个真正的问题.到目前为止我已经考虑了两种方法:

  1. worker角色使用任务的进度和完成更新表行(在表存储中).Web角色没有信号.浏览器直接读取表存储(通过REST api),因此知道任务何时完成.虽然我不喜欢常规轮询的方法,但我希望有一个"基于事件"的解决方案,但这种方法效果很好(我已经测试过了).此外,一旦客户端获得进程已完成的信息,它必须执行对web api方法的附加调用,以向其他客户端(通过SignalR)广播操作已完成.

  2. Interrole通信与SignalR一起使用(参见下面的代码示例)也可以工作(已经过测试)

代码示例:

var protocol = "http";      
var ipAddress = RoleEnvironment.Roles["XXX.YYY.Web"]
        .Instances[0]
        .InstanceEndpoints.ToArray()
        .Where(ep => ep.Value.Protocol == protocol)
        .First()
        .Value.IPEndpoint.ToString();

var stringEndpoint = string.Format("{0}://{1}", protocol, ipAddress.ToString());                
Trace.WriteLine("Retrieved endpoint address: " + stringEndpoint, "Information");            
HubConnection connection = new HubConnection(stringEndpoint);
IHubProxy proxy = connection.CreateHubProxy("MyWebHub");
connection.Start().Wait();

//later...

proxy.Invoke("ProgressUpdated", clientId, progress);
Run Code Online (Sandbox Code Playgroud)

我的问题是:是否还有其他(更好)的方式来沟通方向工作者角色 - > Web角色?也就是说,当一个辅助角色完成处理时,触发Web角色的方法?然后,Web角色上的方法将通过SignalR将更新广播到所有客户端.我还看了一下事件中心,但据我了解,事件消费者仍然会在工作角色上运行.

Mir*_*ano 2

好吧,经过一些额外的尝试和一些研究,我想出了一个可能的解决方案......我正在使用这段代码

AzureServiceBus.QueueClient.OnMessage((message) =>
            {
                try
                {
                    // Process message from queue
                    Trace.WriteLine("Message received: " + ((BrokeredMessage)message).Label);

                    var breezeController = new BreezeController();
                    breezeController.TestSignal();

                    // Remove message from queue
                    message.Complete();
                }
                catch (Exception)
                {
                    // Indicates a problem, unlock message in queue
                    message.Abandon();
                }
            });
Run Code Online (Sandbox Code Playgroud)

在 Web 角色(不是 Worker 角色)的 OnStart 方法中,以便我可以在 Web 角色中引用我的方法(在本例中为 TestSignal()),但事实证明,从此 OnMessage 事件中调用时,IHubContext 始终为 null处理程序,因为它(很可能)属于不同的 AppDomain,因此甚至 signalR 的静态集线器也没有共享。因此,我已将相同的整个代码移至 Global.asax.cs 内,以便它将共享相同的 AppDomain,现在它可以工作了。我想我会继续使用这种方法,因为我比连续轮询更喜欢它。