通过Azure Service Bus传递的SignalR消息不会传播到SignalR Web客户端

时间:2016-07-10 21:25:09

标签: asp.net azure signalr azureservicebus signalr-backplane

我想直接从我的Azure WebJob向我的网络服务器上运行的浏览器客户端发送SignalR消息,因此我已将SignalR配置为使用Azure Service Bus作为WebJob和我的服务器上的背板。从WebJob发送的消息将转到服务总线主题队列,并由Web服务器接收,但不会发送到连接的SignalR Web客户端。我认为这会自动发生,我是否必须以某种方式从Web服务器订阅我的WebJob SignalR消息并手动将它们传播到浏览器客户端?

我粘贴了一些代码,但由于我没有收到任何错误,因此我不确定相关的内容。\ n我可以通过服务总线跟踪来自WebJob的消息到我的Web服务器,但没有任何内容到达每个Web服务器上运行的SignalR浏览器客户端。

突出点;

  • 使用相同的集线器名称
  • 注册每个Hub实例
  • WebJob和Web服务器都使用相同的Service Bus背板连接字符串
  • 我可以看到消息被发送到正确的主题,并且正在阅读正确的订阅

来自WebJob的跟踪信息:

  

SignalR.ServiceBusMessageBus信息:0:订阅服务总线中的5个主题...   SignalR.ServiceBusMessageBus信息:0:成功完成新主题客户端SIGNALR_TOPIC_SignalREvents_0的创建。   SignalR.ServiceBusMessageBus信息:0:在服务总线中成功完成主题SIGNALR_TOPIC_SignalREvents_0的新订阅2ea68ce5-58fe-4218-8768-e03675be8e74的创建。   SignalR.ServiceBusMessageBus信息:0:在服务总线中成功完成订阅实体路径SIGNALR_TOPIC_SignalREvents_0 / Subscriptions / 2ea68ce5-58fe-4218-8768-e03675be8e74的消息接收的创建。   SignalR.ScaleoutMessageBus信息:0:流(0) - 将状态从初始更改为打开   (X5)   SignalR.ServiceBusMessageBus信息:0:订阅服务总线中的5个主题主题服务已成功完成。   SignalR.ServiceBusMessageBus详细:0:通过服务总线发送68个字节:{" H":" auctionHub"," M":" Init" " A":[{"价格":569.72"符号":" GOOG"}]}   SignalR.ServiceBusMessageBus详细:0:通过服务总线发送68个字节:{" H":" auctionHub"," M":" Init" " A":[{"价格":577.38"符号":" APPL"}]}   SignalR.ServiceBusMessageBus详细:0:通过服务总线接收68个字节:{" H":" auctionHub"," M":" Init" " A":[{"价格":569.72"符号":" GOOG"}]}   SignalR.ScaleoutMessageBus信息:0:OnReceived(4,65,1)

来自网络服务器的跟踪

  

SignalR.ServiceBusMessageBus信息:0:订阅5   服务总线中的主题... SignalR.ServiceBusMessageBus   信息:0:创建新主题客户端   SIGNALR_TOPIC_SignalREvents_0已成功完成。   SignalR.ServiceBusMessageBus信息:0:创建新的   订阅e6afd744-7724-4ab5-8fd9-2717a62caf61,主题SIGNALR_TOPIC_SignalREvents_0已成功完成服务总线。 SignalR.ServiceBusMessageBus信息:0:在服务总线中成功完成订阅实体路径SIGNALR_TOPIC_SignalREvents_0 / Subscriptions / e6afd744-7724-4ab5-8fd9-2717a62caf61的消息接收创建。   SignalR.ScaleoutMessageBus信息:0:流(0) - 将状态从初始更改为打开   SignalR.ServiceBusMessageBus信息:0:创建新主题   客户端SIGNALR_TOPIC_SignalREvents_1已成功完成。   SignalR.ServiceBusMessageBus信息:0:创建新的   订阅2c155757-123f-44ba-ace7-96a6b390234e主题   服务总线中的SIGNALR_TOPIC_SignalREvents_1已完成   成功。 SignalR.ServiceBusMessageBus信息:0:创建   接收订阅实体路径的消息   SIGNALR_TOPIC_SignalREvents_1 /订阅/ 2c155757-123f-44ba-ace7-96a6b390234e   在服务总线上成功完成。 SignalR.ScaleoutMessageBus   信息:0:流(1) - 将状态从初始更改为打开   SignalR.ServiceBusMessageBus信息:0:创建新主题   客户端SIGNALR_TOPIC_SignalREvents_2已成功完成。   SignalR.Transports.TransportHeartBeat信息:0:连接   869c61bb-5070-4c64-811a-9a3612eff981是新的。

     

SignalR.ServiceBusMessageBus详细:0:接收37个字节   服务巴士:{" H":" auctionHub"," M":" Init"," A":[ 1]}   SignalR.ScaleoutMessageBus信息:0:OnReceived(4,221,1)

SignalR服务总线配置代码(在WebJob和Web服务器上相同)

var scaleOutConfig = new ServiceBusScaleoutConfiguration(ConfigurationManager.ConnectionStrings["AzureWebJobsServiceBus"].ConnectionString, "SignalREvents");
GlobalHost.DependencyResolver.UseServiceBus(scaleOutConfig);

如果我留下任何头发,我会把它撕掉。我对此进行了广泛的搜索,但是找不到任何有用的东西。任何指针都将非常感激。

修改>>

[HubName("auctionHub")]
public class AuctionHub : Hub<IAuctionHubClientMethods>
{
    private readonly IAuctionHubService _auctionHubService;

    public AuctionHub(IAuctionHubService auctionHubService)
    {
        _auctionHubService = auctionHubService;
    }

    public override Task OnConnected()
    {
        var userId = Context.User.Identity.GetUserId();
        var connectionId = Context.ConnectionId;
        _auctionHubService.OnConnected(Groups, userId, connectionId);
        return base.OnConnected();
    }

public interface IAuctionHubClientMethods
{
    Task Heartbeat(string now);
    Task Init(AuctionViewModel eventId);
}

public class AuctionHubService : IAuctionHubService
{
    <snip>

    public AuctionHubService(IAuctionServices auctionServicesProxy, IQueryProcessor queryProcessor, ApplicationUserManager userManager)
    {
         <snip>
    }

    public void OnConnected(IGroupManager groups, string userId, string connectionId)
    {
        var user = _userManager.FindById(userId);
        var client = user.Client;
        var id = client?.Id;
        groups.Add(connectionId, user.Client.Id.ToString());
    }

    public void Init(int eventId, IHubCallerConnectionContext<IAuctionHubClientMethods> clients)
    {
        var query = new GetAuctionViewModelByEventIdQuery { EventId = eventId };
        var eventState = _queryProcessor.Process(query);
        eventState.Suppliers.ForEach(x => clients.Group(x.SupplierId.ToString()).Init(eventState));
    }
}

OnDisconnectedOnReconnected未受影响。

我正在使用SimpleInjector根据需要提供SignalR上下文,这个实现会有效吗?

 var hubConfiguration = new HubConfiguration
        {
            EnableDetailedErrors = true,
            EnableJavaScriptProxies = false,
            Resolver = new SignalRDependencyResolver(MvcApplication.Container),
        };

app.MapSignalR<SignalRHubDispatcher>("/signalr", hubConfiguration);

public class SignalRHubDispatcher : HubDispatcher
{
    public SignalRHubDispatcher(Container container, HubConfiguration configuration) : base(configuration)
    {
        _container = container;
    }

    protected override Task OnConnected(IRequest request, string connectionId)
    {
        return Invoke(() => base.OnConnected(request, connectionId));
    }

    protected override Task OnReceived(IRequest request, string connectionId, string data)
    {
        return Invoke(() => base.OnReceived(request, connectionId, data));
    }

    protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled)
    {
        return Invoke(() => base.OnDisconnected(request, connectionId, stopCalled));
    }

    protected override Task OnReconnected(IRequest request, string connectionId)
    {
        return Invoke(() => base.OnReconnected(request, connectionId));
    }

    private async Task Invoke(Func<Task> method)
    {
        using (_container.BeginExecutionContextScope())
        {
            await method();
        }
    }

    private readonly Container _container;
}

0 个答案:

没有答案