本文介绍了通过SignalR HubContext从位于集线器之外的项目中的方法发送消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WebAPI项目,其中API,服务和数据层都在同一解决方案的单独项目中.作为服务项目中方法的一部分,我想向API项目中集线器的已连接客户端发送消息.到目前为止,我发现的所有示例都在一个项目中包含所有内容,并使用控制器作为通过集线器发送消息的示例.

I have a WebAPI project where the API, Service and Data layers are all in separate projects of the same solution. As part of a method in my Service project, I want to send a message to the connected clients of a hub in the API project. So far all of the examples I have found have everything in a single project and use a controller as the example sending a message via a hub.

我已经尝试了依赖注入(Autofac),但是无法获得对MessageHub的引用.

I've tried dependency injection (Autofac) however I am unable to get a reference to the MessageHub.

[HubName("messages")]
public class MessageHub : Hub
{
    public void ShowNewMessage(string message)
    {
        Clients.All.showMessageOnPage(message);
    }
}

在这里可以看到我的注入尝试:将SignalR IHubContext注入Autofac的服务层

My attempt at Injecting can be seen here: Inject SignalR IHubContext into service layer with Autofac

推荐答案

请查看此选项:

  1. 在服务(或更好的域)层项目中定义通用集线器接口.类似于 IMessageBroker .
  2. 在表示层(WebAPI)项目内部实现此接口,并使用 IConnectionManager 进行HubContext检索.
  3. 在表示层的IoC容器(Autofac)中注册接口
  4. 将界面插入App Service内部
  1. Define generic hub interface in your Service (or better Domain) Layer project. Something like IMessageBroker.
  2. Inside your Presentation Layer (WebAPI) project implement this interface and use IConnectionManager for HubContext retrieving.
  3. Register the interface in an IoC Container (Autofac) in the Presentation Layer
  4. Inject the interface inside App Service

伪代码:

域层:

public interface IMessageBroker
{
    void ShowNewMessage(string message)
}

服务层:

public class NotificationService: INotificationService
{
    private readonly IMessageBroker _messageBroker;

    public NotificationService(IMessageBroker messageBroker)
    {
        _messageBroker = messageBroker;
    }

    public void RunNotification(string message)
    {
        _messageBroker.ShowNewMessage(message);
    }
}

演示层:

[HubName("messages")]
public class MessageHub: Hub
{
    public void ShowNewMessage(string message)
    {
        Clients.All.showMessageOnPage(message);
    }
}


public class MessageBroker: IMessageBroker
{
    private readonly IConnectionManager _connectionManager;

    public MessageBroker(IConnectionManager connectionManager)
    {
        _connectionManager = connectionManager;
    }

    public void ShowNewMessage(string message)
    {
        var hub = _connectionManager.GetHubContext<MessageHub>();
        // Use Hub Context and send message
    }
}

Autofac注册(演示层):

// Register Hubs
builder.RegisterHubs(Assembly.GetExecutingAssembly());

// Register Autofac resolver into container to be set into HubConfiguration later
builder.RegisterType<AutofacDependencyResolver>().As<IDependencyResolver>().SingleInstance();

// Register ConnectionManager as IConnectionManager so that you can get hub context via IConnectionManager injected to your service
builder.RegisterType<ConnectionManager>().As<IConnectionManager>().SingleInstance();

// Register interface
builder.RegisterType<MessageBroker>().As<IMessageBroker>();

也可以使用类似的SO主题.

Also similar SO topic is available here.

这篇关于通过SignalR HubContext从位于集线器之外的项目中的方法发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!