SignalR:必须先启动连接,然后才能发送数据。 在.send()之前调用.start()

直到最近才开始使用SignalR,我几天前就已经开始工作,现在无法解决出错的问题。

我有我的中心:

[HubName("roleManagementHub")] public class RoleManagementHub : GenericHub { public RoleManagementHub(ICurrentlyViewingUserService service) : base(service) { } } 

这扩展了我创建的通用集线器:

 public class GenericHub : Hub where TEntity : class, IBusinessObject { private readonly ICurrentlyViewingUserService service; public GenericHub(ICurrentlyViewingUserService service) { this.service = service; } public void ImViewing(string id) { string colour; service.AddCurrentlyViewingUser(id, HttpContext.Current.User.Identity.Name, out colour); Clients.handleImViewingMessage(HttpContext.Current.User.Identity.Name, colour, id); } public void ImLeaving(string id) { service.RemoveCurrentlyViewingUser(id, HttpContext.Current.User.Identity.Name); Clients.handleImLeavingMessage(HttpContext.Current.User.Identity.Name, id); } public void IHaveEdited(string id, string property, string content) { string colour = service.GetCurrentlyViewingUserColour(id, HttpContext.Current.User.Identity.Name); if (string.IsNullOrEmpty(colour)) return; Clients.handleIHaveEdited(id, property, content); } } 

我包括

现在到主要的javascript。 我创建了一个可重用的Knockout JS组件,它接收集线器以连接相关的处理程序。 很多这都是无关紧要的,但我想我会把它全部发布。 我在闭包开始时开始我的连接,并在roleManagementHub中创建传递的knockout组件。

 var user_role_edit = {}; (function (index) { user_role_edit = index; jQuery.connection.hub.start(); var val = ko.setupValidation([], []); val.createErrorCollections({Name: 0, General: 0}, index, 'rename-role-form'); var dmp = new diff_match_patch(); index.Id = ko.observable(); index.Name = ko.observable(); index.currentViewersViewModel = new ko.currentlyViewingComponent.viewModel({ hub: jQuery.connection.roleManagementHub, id: index.Id, modalSelector: '#user-role-edit-modal' }); index.rename = function (form) { jQuery.post('" + @Url.Action("Rename", "RoleManagement") + @"', { 'id': index.Id(), 'name': index.Name() }, function (dataReturned) { if (dataReturned.IsValid) { jQuery(document).trigger('userRoleUpdated', index); index.editModal.modal('hide'); } else { val.rebindValidations({Name: 0, General: 0}, index, dataReturned.Errors); } }); }; index.raiseClose = function () { index.editModal.modal('hide'); }; index.raiseDetails = function () { jQuery(document).trigger('userRoleDetails', [index]); index.editModal.modal('hide'); } jQuery(document).bind('userRoleEdit', function (event, id) { jQuery.getJSON('" + @Url.Action("GetNewsArticleForUpdateOrDelete", "RoleManagement") + @"', { id: id }, function (data) { index.Id(data.Role.Id); index.Name(data.Role.Name); index.currentViewersViewModel.initialiseCurrentViewers(data.CurrentlyViewingUsers); val.clearValidations({Name: 0, General: 0}, index); index.editModal.modal('show'); }); }); jQuery.connection.roleManagementHub.handleIHaveEdited = function(id, property, content) { if (index.Id() != id) return; if (index[property] == undefined) return; dmp.Match_Distance = 1000; dmp.Match_Threshold = 0.5; dmp.Patch_DeleteThreshold = 0.5; var patches = dmp.patch_make(index[property](), content); var results = dmp.patch_apply(patches, index[property]()); index[property](results[0]); }; jQuery(function () { ko.applyBindings(index, jQuery('#user-role-edit-container')[0]); index.editModal = jQuery('#user-role-edit-modal').modal({ backdrop: true, closeOnEscape: true, modal: true, show: false }); jQuery('#rename-role-form > fieldset > div > div > input#Name').blur(function(event) { jQuery.connection.roleManagementHub.iHaveEdited(index.Id(), 'Name', index.Name()); }); }); } (user_role_edit));"); 

这是淘汰赛组件:

 (function () { function currentUserViewModel(username, colour) { this.Username = username; this.Colour = colour; } ko.currentlyViewingComponent = { // Defines a view model class you can use to populate a grid viewModel: function (configuration) { this.currentViewers = ko.observableArray([]); var index = this; this.initialiseCurrentViewers = function (currentUsers) { index.currentViewers.removeAll(); ko.utils.arrayForEach(currentUsers, function (item) { index.currentViewers.push(new currentUserViewModel(item.Username, item.Colour)); }); }; configuration.hub.handleImViewingMessage = function (username, colour, id) { if (configuration.id() != id) return; var findResult = ko.utils.arrayFirst(index.currentViewers(), function (item) { return item.Username == username; }); if (findResult == null) index.currentViewers.push(new currentUserViewModel(username, colour)); jQuery('a[rel=tooltip]').tooltip(); }; configuration.hub.handleImLeavingMessage = function (username, id) { if (configuration.id() != id) return; index.currentViewers.remove(function (item) { return item.Username == username; }); }; jQuery(configuration.modalSelector).bind('show', function () { configuration.hub.imViewing(configuration.id()); }); jQuery(configuration.modalSelector).bind('hide', function () { configuration.hub.imLeaving(configuration.id()); }); } }; // Templates used to render the grid var templateEngine = new ko.nativeTemplateEngine(); templateEngine.addTemplate = function (templateName, templateMarkup) { document.write("" + templateMarkup + ""); }; templateEngine.addTemplate("ko_currentlyViewing", ""); ko.bindingHandlers.currentlyViewingComponent = { init: function () { return { 'controlsDescendantBindings': true }; }, // This method is called to initialize the node, and will also be called again if you change what the grid is bound to update: function (element, viewModelAccessor, allBindingsAccessor) { var viewModel = viewModelAccessor(), allBindings = allBindingsAccessor(); // Empty the element while (element.firstChild) ko.removeNode(element.firstChild); // Allow the default templates to be overridden var currentlyViewingTemplateName = allBindings.currentlyViewingTemplate || "ko_currentlyViewing"; // Render the main grid var currentlyViewingContainer = element.appendChild(document.createElement("DIV")); ko.renderTemplate(currentlyViewingTemplateName, viewModel, { templateEngine: templateEngine }, currentlyViewingContainer, "replaceNode"); } }; 

})();

正如您在模态显示事件中看到的那样,它使用集线器发送消息,告诉其他连接用户用户已开始查看该项目。

但是我现在迎接“SignalR:必须先启动连接才能发送数据。在.send()之前调用.start()”。

我已经开始连接了! 即使我尝试;

 jQuery(function() { jQuery.connection.hub.start(); jQuery.connection.userManagementHub.imViewing("1"); }); 

我得到Connection必须在数据发送之前启动消息。

有任何想法吗??

提前致谢!

乔恩

start()的调用不是即时的,可能是导致问题的原因。 您可能希望将启动后应该发生的代码移动到start方法中的回调中,如:

 jQuery(function(){ jQuery.connection.hub.start(function(){ jQuery.connection.userManagementHub.imViewing("1"); }); });