【发布时间】:2015-07-08 13:59:59
【问题描述】:
我最近使用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);
}
}
但如果我尝试利用 Abp 的 EventBus 的优势,那么我实现了我的 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 作为代理和我想走的新方式之间没有改变。
用于处理信号器的客户端插件
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());
}
}
【问题讨论】:
-
可以关闭,但是客户端定义的
entryCreated函数在哪里? -
感谢您的评论,您在发布的代码中是正确的,因为我重命名了类和方法,因此出现错误。必须更改行 myHubProxy .on('entryCreated', onCreated);在实际代码中方法名称写得正确
-
OnCreated 回调是唯一未达到的回调吗?
-
都没有调用,只是到达了onStartedCallback
-
所以我同意,这一定是 JS 代码中的问题,很可能我认为这是范围问题。 onStarted 是作为 done 委托传递的,其他的附加在 myHubProxy 上。
标签: javascript signalr durandal event-bus asp.net-boilerplate