2013-05-22 46 views
7

我無法弄清楚如何從WebAPI ApiController調用SignalR集線器。我已經組建了一個示例,您可以下載here來簡化問題並演示此問題。從WebAPI控制器問題調用SignalR集線器

  1. 我從ASP.NET MVC WebAPI模板創建了一個新項目。
  2. 我在項目中添加了一個名爲ChatHub的新SignalR Hub。
  3. 添加了一個加載的HTML頁面,連接到ChatHub,加入到一個組中,並向該組發送消息。這很好。
  4. HTML頁面還有一個按鈕,點擊後會觸發ajax調用ValuesController的post方法。在ValuesController的post方法中,我想向組中所有連接的客戶端廣播一條消息。我無法得到這個工作。

我有一個簡單的SignalR集線器,只有2種方法。

[HubName("chat")] 
public class ChatHub : Hub 
{ 
    public void Join(string room) 
    { 
     // NOTE: this is not persisted - .... 
     Groups.Add(Context.ConnectionId, room); 
    } 

    public void Send(string room, string message) 
    { 
     var msg = String.Format(
      "{0}: {1}", Context.ConnectionId, message); 
     Clients.Group(room).newMessage(msg); 
    } 
} 

我創建了一個非常簡單的HTML頁面,它在DOM準備就緒時連接到Chat hub,如下所示。

<html> 
<head> 
    <title>Simple Chat</title> 
    <script src="Scripts/jquery-1.8.2.js" type="text/javascript"></script> 
    <script src="Scripts/jquery.signalR-1.0.0.js"></script> 
    <script src="signalr/hubs"></script> 
    <script type="text/javascript"> 
     var chat; 

     //$(function() { 
     // connectToHubs(); 
     //}); 
     $(connectToHubs); 
     function connectToHubs() { 
      $.connection.hub.logging = true; 

      chat = $.connection.chat; 
      chat.client.newMessage = onNewMessage; 

      $.connection.hub.start({ transport: 'longPolling' }).done(function() { 
       chat.server.join("TestGroup").done(function() { 
        chat.server.send("TestGroup", "message from html"); 
       }); 
      }); 

      $('#controller').click(postProficiencyUserAction); 



     } 
     var postProficiencyUserAction = function() { 
      //var token = $('[name=__RequestVerificationToken]').val(); 
      var headers = {}; 
      //headers["__RequestVerificationToken"] = token; 
      //var userAction = { createdOn: "2013-05-21T00:00:00", userId: "12345678-1234-1234-1234-000000000001", actionId: "12345678-1234-1234-1234-000000000003" }; 
      $.ajax({ 
       type: 'POST', 
       url: 'http://localhost:58755/api/values', 
       cache: false, 
       headers: headers, 
       contentType: 'application/json; charset=utf-8', 
       data: 'test', 
       dataType: "json", 
       success: function() { 

       }, 
       error: function() { 

       } 
      }); 
     }; 
     function onNewMessage(message) { 
      // ... todo: validation !!!! :) 
      $('#messages').append('<li>' + message + '</li>'); 
     }; 

    </script> 
</head> 
<body> 
    <div> 
     <h2>Chat</h2> 
     <input type="button" id="controller" value="Controller Method" /> 
     <div> 
      <h2>Message(s) Received</h2> 
      <ul id="messages"></ul> 
     </div> 
    </div> 
</body> 
</html> 

沒什麼特別的。只要連接的集線器收到新消息,就會將新項目添加到無序列表中。有一個按鈕可以將Ajax調用放入ValuesController後處理方法中。

public class ValuesController : ApiController 
{ 
    // POST api/values 
    public void Post([FromBody]string value) 
    { 
     var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>(); 
     hubContext.Clients.Group("TestGroup").send("TestGroup", "Called from Controller"); 
    } 

集線器呼叫不起作用。不會拋出錯誤,但從未接收到該消息。在Hub的「Send」方法中放置斷點也不起作用。我覺得我做對了。任何人幫助?同樣,源代碼可以發現here

回答

14

您所呼叫的客戶端上的不同的方法:

API控制器

hubContext.Clients.Group("TestGroup").send("TestGroup", "Called from Controller"); 

樞紐

Clients.Group(room).newMessage(msg); 

要調用的方法是NewMessage作爲不發送

chat.client.newMessage = onNewMessage; 
+0

大衛,非常感謝。所以它出現在服務器上,我可以調用HubContext.Clients.Group(「TestGroup」)的任何方法,比如hubContext.Clients.Group(「TestGroup」)。helloNasty,客戶端將自動地響應相同的編制方法。瘋。我需要研究C#動態功能:-) – DapperDanh

+0

這就是要點:) – davidfowl

+0

@dfowler:有沒有什麼辦法可以從ApiController調用實際的ChatHub.Send方法?上面這種做法似乎是繞過ChatHub,直接轉到Hub上下文來完成ChatHub.Send的功能 - 但ChatHub.Send中的任何其他功能都不會運行。這需要在ApiController?也許我只是在這裏錯過了一些東西。 – mutex