2012-03-22 13 views
0

SignalRを使用し始めたのは数日前ですが、これはうまくいきませんでした。私が作成した汎用的なハブを拡張SignalR:データを送信する前に接続を開始する必要があります。 .send()の前に.start()を呼び出してください。

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

::私は<script type="text/javascript" src="@Url.Content("~/signalr/hubs")"></script>含めてい

public class GenericHub<TEntity> : Hub where TEntity : class, IBusinessObject<TEntity> 
{ 
    private readonly ICurrentlyViewingUserService service; 

    public GenericHub(ICurrentlyViewingUserService service) 
    { 
     this.service = service; 
    } 

    public void ImViewing(string id) 
    { 
     string colour; 
     service.AddCurrentlyViewingUser<TEntity>(id, HttpContext.Current.User.Identity.Name, out colour); 
     Clients.handleImViewingMessage(HttpContext.Current.User.Identity.Name, colour, id); 
    } 

    public void ImLeaving(string id) 
    { 
     service.RemoveCurrentlyViewingUser<TEntity>(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<TEntity>(id, HttpContext.Current.User.Identity.Name); 

     if (string.IsNullOrEmpty(colour)) 
      return; 

     Clients.handleIHaveEdited(id, property, content); 
    } 
} 

は、私は私のハブを持っています。

今すぐメインのJavaScriptに。私は、再利用可能なノックアウトJSコンポーネントを作成して、関連するハンドラをアタッチするハブを取ります。これの多くは無関係ですが、私はそれをすべて入れておくと思っていました。私は閉鎖の冒頭で私の接続を開始し、私のノックアウトコンポーネントをroleManagementHubで渡すように作成します。ここ

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("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>"); 
}; 

templateEngine.addTemplate("ko_currentlyViewing", "<div data-bind=\"foreach: currentViewers\" class=\"pull-left\"><a data-bind=\"attr: { title: Username, 'class': Colour }\" rel='tooltip'>&nbsp;</a></div>"); 

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()を呼び出してください。

私は既に接続を開始しました!私が試してみても。

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

データが送信される前にConnectionを開始する必要があります。

ありがとうございました!

ジョン

答えて

10

start()への呼び出しは、インスタントではなく、あなたの問題の原因である可能性があります。開始メソッドのコールバックに開始後に発生するコードを次のように移動することができます。

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

お寄せいただきありがとうございます。明日私は家にいるときにこれを試してみる。しかし、私はこの最後の夜を試みたとかなり確信しており、接続は決して始まらないようです。接続が開始されていないことがありますか? –

+0

ねえ、これを試してもまだ動作しません。シグナルをデバッグするのは、signalRがsignalR/negotiateを要求しているが、決してレスポンスを返さない場合のようです。 –

+1

@JonathanStowell好奇心、依存性注射を使用していますか?その場合、ハブを正しく解決していない可能性があります。 –

関連する問題