使用SignalR从Azure Worker Role向客户端发送消息

时间:2015-01-19 10:09:03

标签: asp.net asp.net-mvc azure signalr azure-worker-roles

我正在运行一个ASP.net MVC云服务项目,该项目运行两个角色,一个Web角色和一个辅助角色。 Web角色中的一个页面发起构建APK文件的请求,在服务器上构建APK文件可能需要1-5分钟。所以我们想出了以下流程:

  1. 用户在页面上启动APK构建过程。
  2. 请求将路由到我们的mvc操作,在Azure存储队列上创建新邮件。
  3. Worker角色始终从队列中轮询并启动APK构建过程。现在APK准备好了,我们理想地通过以下方式通知用户: (a)发送一封现在正在运作的电子邮件。 (b)使用SignalR在页面上通知用户。
  4. 我们的问题现在在SignalR部分,我们如何在页面上通知用户APK已准备好并可以下载。

1 个答案:

答案 0 :(得分:1)

编辑 - 为了完整起见,复制第一条评论的内容 -

我再次查看了这个问题,我知道您正在使用辅助角色来轮询队列。在这种情况下,您可以将您的工作角色设置为连接到Web角色上的APK signalR hub的.Net SignalR客户端。 Web角色上的signlaR中心可以简单地将从.Net客户端收到的任何消息转发到javascript客户端(浏览器)。

我建议通过以下链接

Hubs API Guide - Server
Hubs API Guide - Javascript Client

在完成其余的答案之前。

从以上两个链接可以理解,SignalR使服务器能够“推送”。数据到客户端。为了实现这一点,您需要两件事 -

  1. 信号集线器 - 这是集线器'客户可以订阅以接收消息。
  2. 连接到集线器的客户端
  3. 服务器上的signalR集线器看起来像这样 -

        public class APKHub : Hub
        {
            public async Task JoinGroup(string groupName)
            {
                await Groups.Add(Context.ConnectionId, groupName);
                Clients.Group(groupName).sendMessage(Context.User.Identity.Name + " joined.");
            }
    
            public Task LeaveGroup(string groupName)
            {
                return Groups.Remove(Context.ConnectionId, groupName);
            }
    
            public void NotifyUser(string userId)
            {
                this.Clients.Group(userId).notify();
            }
        }
    

    在客户端上,您的代码可能看起来像这样 -

    var notificationHandler = function () {
    
    var url;
    var user;
    
    var init = function (notificationUrl, userId) {
    
        url = notificationUrl;
        user = userId;
    
        connectToAPKHub();
    }
    
    var connectToAPKHub = function () {
        $.connection.hub.url = url;
        var apk= $.connection.apkHub;
    
        apk.client.notifyUser = function (user) {
            console.log(user);            
        }
    
        apk.client.addMessage = function (message) {
            console.log(message);
        }
    
        $.connection.hub.start().done(function () {
            console.log('connected to apkhub');
            apk.server.joinGroup(user);
        })
    }
    
    
    return {
        init: init
    }
    }();
    

    notificationUrl是signalR服务器正在侦听的URL。

    这将在服务器上设置您的基本集线器,您现在应该可以将客户端连接到signalR集线器。构建APK时,您可以使用以下代码(将其置于任何位置 - 例如,在控制器操作中)以实际将消息推送到相关客户端 -

    var apkHub = GlobalHost.ConnectionManager.GetHubContext<APKHub>();
    apkHub.Clients.Group(groupName).notifyUser(groupName);
    

    groupName可以是唯一标识用户的标识符。

    希望这有帮助。