gpt4 book ai didi

javascript - 使用 SignalR 作为 EventBus 事件的广播者

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:03:09 24 4
gpt4 key购买 nike

我最近用 AspBoilerplate 开始了一个新项目(Abp) 并使用 SignalR 作为某种广播机制来告知连接的客户端数据库中的某些记录是否已更改或添加或删除。如果我使用 SignalR Hub 作为我的 AppService 的代理,一切正常,客户端会收到通知

public class TestHub : Hub
{
IMyAppService = _service
public TestHub(IMyAppService service)
{
_service = service;
}

public void CreateEntry(EntryDto entry)
{
_service.Create(entry);
Clients.All.entryCreated(entry);
}
}

但如果我尝试利用 EventBus 的优势Abp 所以我实现了我的 AppSevice 以将事件发送到 EventBus:

class MyAppService : ApplicationService, IMyAppService 
{
public IEventBus EventBus { get; set; }

private readonly IMyRepository _myRepository;


public LicenseAppService(ILicenseRepository myRepository)
{
EventBus = NullEventBus.Instance;
_myRepository = myRepository;
}

public virtual EntryDto CreateLicense(EntryDto input)
{
var newEntry = Mapper.Map<EntryDto >(_myRepository.Insert(input));

EventBus.Trigger(new EntryCreatedEventData { Entry = newEntry});
return newEntry;
}
}

然后我尝试直接将集线器用作 EventHandler,但这失败了,因为 abp 在需要处理事件时会创建自己的 EventHandler 类实例。但这里的代码只是为了完整性:

public  class TestHub : Hub,
IEventHandler<EntryCreatedEventData>
{
public void Handle(EntryCreatedEventData data)
{
Clients.All.entryCreated(data.Entry);
}
}

在此之后我创建了一个单独的 Listener 类并尝试像这样使用集线器上下文并使用一个非常空的集线器:

public  class TestHub : Hub
{
}

public class EntryChangeEventHandler : IEventHandler<EntryCreatedEventData>
{
private IHubContext _hubContext;
public EntryChangeEventHandler()
{
_hubContext = GlobalHost.ConnectionManager.GetHubContext<TestHub>();

public void Handle(EntryCreatedEventData data)
{
_hubContext.Clients.All.entryCreated(eventData.Entry);
}
}

在最后一个解决方案中,一切都运行到线

_hubContext.Clients.All.entryCreated(eventData.Entry);

但在我的 javascript 实现的客户端,该方法从未被调用。客户端(基于 DurandalJs)在使用 Hub 作为代理和我想要的新方式之间没有改变。

用于与 signalr 一起工作的客户端插件

define(["jquery", "signalr.hubs"],
function ($) {
var myHubProxy


function connect(onStarted, onCreated, onEdited, onDeleted) {

var connection = $.hubConnection();
myHubProxy = connection.createHubProxy('TestHub');

connection.connectionSlow(function () {
console.log('We are currently experiencing difficulties with the connection.')
});
connection.stateChanged(function (data) {
console.log('connectionStateChanged from ' + data.oldState + ' to ' + data.newState);
});

connection.error(function (error) {
console.log('SignalR error: ' + error)
});

myHubProxy .on('entryCreated', onCreated);
myHubProxy .on('updated', onEdited);
myHubProxy .on('deleted', onDeleted);
connection.logging = true;
//start the connection and bind functions to send messages to the hub
connection.start()
.done(function () { onStarted(); })
.fail(function (error) { console.log('Could not Connect! ' + error); });
}

return signalr =
{
connect: connect
};
});

使用插件查看:

define(['jquery', 'signalr/myHub],
function ($, myHubSR) {
return function () {
var that = this;
var _$view = null;

that.attached = function (view, parent) {
_$view = $(view);
}

that.activate = function () {
myHubSR.connect(that.onStarted, that.onCreated, that.onEdited, that.onDeleted);
}

that.onStarted= function () {
//do something
}
that.onCreated= function (data) {
//do something
}
that.onEdited = function (data) {
//do something
}
that.onDeleted= function (data) {
//do something
}
}
});

所以任何人都知道为什么在我调用时从不调用 onCreated

_hubContext.Clients.All.entryCreated(eventData.Entry);

?

为了测试 signalR 通信是否有效,我添加了一个直接调用客户端方法的方法。调用此方法更新成功推送到客户端。所以我认为问题在于使用 IHubContext 对所有客户端的远程调用是否有任何线索在使用 IHubContext 时可能出现什么问题?

public class TestHub : Hub
{
public TestHub ()
:base()
{ }

public void Test()
{
this.Clients.All.entryCreated(new EntryDto());
}
}

最佳答案

首先,你有没有给DI注册过EntryChangeEventHandler?如果没有,还为 EntryChangeEventHandler 实现 ITransientDependency 接口(interface)。

您的问题可能与序列化有关。它可能不会序列化 eventData.Entry。您可以尝试发送另一个 DTO 对象。

另外,你可以实现

IEventHandler<EntityChangedEventData<Project>>

为了监听项目实体中的所有更改(包括插入、更新和删除)。 Project 在这里只是一个示例实体。

对于您的第一个案例,如果未注册到 DI,TestHub 将无法工作。您还可以为 TestHub 类实现 ITransientDependency。你应该让 SignalR 从 DI 容器中获取它。你可以为它使用这样一个类:

public class WindsorDependencyResolver : DefaultDependencyResolver
{
public override object GetService(Type serviceType)
{
return IocManager.Instance.IocContainer.Kernel.HasComponent(serviceType) ? IocManager.Instance.IocContainer.Resolve(serviceType) : base.GetService(serviceType);
}

public override IEnumerable<object> GetServices(Type serviceType)
{
return IocManager.Instance.IocContainer.Kernel.HasComponent(serviceType) ? IocManager.Instance.IocContainer.ResolveAll(serviceType).Cast<object>() : base.GetServices(serviceType);
}
}

然后在启动时设置它:

GlobalHost.DependencyResolver = new WindsorDependencyResolver();

也许我的回答有点困惑:)希望你能理解。

关于javascript - 使用 SignalR 作为 EventBus 事件的广播者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31294992/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com