首页 文章

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

提问于
浏览
4

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

  • 用户在页面上启动APK构建过程 .

  • 请求被路由到我们的mvc操作,在Azure存储队列上创建新消息 .

  • Worker角色始终从队列中轮询并启动APK构建过程 . 现在APK准备就绪,我们希望通过以下方式通知用户:(a)发送一封现在正在运行的电子邮件 . (b)使用SignalR在页面上通知用户 .

我们的问题现在在SignalR部分,我们如何在页面上通知用户已准备好APK并可以下载它 .

1 回答

  • 1

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

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

    我建议通过以下链接

    Hubs API Guide - Server
    Hubs API Guide - Javascript Client

    在完成其余的答案之前 .

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

    • signalR hub - 这是客户可以订阅以便接收消息的'hub' .

    • 连接到集线器的客户端

    您在服务器上的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可以是唯一标识用户的标识符 .

    希望这可以帮助 .

相关问题