使用 SignalR 从 Azure 工作者角色向客户端发送消息

Using SignalR to send message to client from Azure Worker Role

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

  1. 用户在页面上启动 APK 构建过程。
  2. 请求被路由到我们的 mvc 操作,在 Azure 存储队列上创建一条新消息。
  3. Worker 角色始终从队列中轮询并启动 APK 构建过程。现在 APK 已准备就绪,我们希望通过以下方式通知用户: (a) 发送电子邮件,现在可以使用。 (b) 使用 SignalR 在页面上通知用户。

我们现在的问题是在SignalR部分,我们如何在页面上通知用户APK已经准备好,他可以下载了。

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

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

我建议浏览以下链接

Hubs API Guide - Server
Hubs API Guide - Javascript Client

在完成其余答案之前。

从上面两个链接可以了解到,SignalR使服务端能够'push'数据到客户端。为了实现这一点,您需要做两件事 -

  1. signalR 集线器 - 这是 'hub' 客户端可以订阅以接收消息的集线器。
  2. 连接到集线器的客户端

服务器上的 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);

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

希望对您有所帮助。