2013-05-22 35 views
7

Tôi không thể tìm ra cách tôi có thể gọi vào một trung tâm SignalR từ một WebAPI ApiController. Tôi đã đặt cùng một mẫu bạn có thể tải xuống here để đơn giản hóa vấn đề và giải thích vấn đề.gọi SignalR hub từ các vấn đề điều khiển WebAPI

  1. Tôi đã tạo một dự án mới từ mẫu ASP.NET MVC WebAPI.
  2. Tôi đã thêm Hub SignalR mới vào dự án có tên ChatHub.
  3. Đã thêm trang HTML khi tải, kết nối với ChatHub, tham gia nhóm và gửi thư đến nhóm đó. Điều này làm việc tuyệt vời.
  4. Trang HTML cũng có nút khi được nhấp sẽ kích hoạt cuộc gọi ajax đến phương thức bài của ValuesController. Trong phương thức post của ValuesController, tôi muốn phát một thông báo tới tất cả các client đã kết nối của nhóm. Tôi không thể làm việc này được.

Tôi có một trung tâm SignalR đơn giản chỉ với 2 phương pháp.

[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); 
    } 
} 

Tôi đã tạo một trang HTML rất đơn giản kết nối với Trung tâm trò chuyện khi DOM sẵn sàng như được hiển thị tại đây.

<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> 

Không có gì lạ mắt. Bất cứ khi nào hub kết nối nhận được một tin nhắn mới, một mục mới sẽ được thêm vào danh sách không có thứ tự. Có một nút thực hiện cuộc gọi Ajax vào phương thức post 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"); 
    } 

Cuộc gọi Hub không hoạt động. Một lỗi không được ném, nhưng, tin nhắn không bao giờ nhận được. Đặt điểm ngắt trong phương thức "Gửi" của Hub cũng không hoạt động. Tôi cảm thấy như tôi đang làm đúng. Bất cứ ai giúp đỡ? Một lần nữa, mã nguồn có thể được tìm thấy here

Trả lời

14

Bạn đang kêu gọi các phương pháp khác nhau trên máy khách:

điều khiển API

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

Hub

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

Phương pháp bạn muốn gọi là newMessage không gửi

chat.client.newMessage = onNewMessage; 
+0

David, cảm ơn rất nhiều. Vì vậy, nó xuất hiện trên máy chủ, tôi có thể gọi bất kỳ phương thức nào của hubContext.Clients.Group ("TestGroup") chẳng hạn như hubContext.Clients.Group ("TestGroup"). HelloNasty và máy khách sẽ tự động có thể phản hồi lại điều đó tạo thành phương pháp. Khùng. Tôi cần phải nghiên cứu về khả năng động C# :-) – DapperDanh

+0

Đó là điểm :) – davidfowl

+0

@dfowler: Có cách nào để gọi phương thức ChatHub.Send thực tế từ ApiController không? Cách làm trên dường như bỏ qua ChatHub và chỉ cần đi thẳng đến Hub Context để làm việc tương đương với những gì ChatHub.Send thực hiện - nhưng bất kỳ điều gì khác tôi có trong ChatHub.Send sẽ không chạy \ sẽ cần phải được nhân rộng trong ApiController? Có lẽ tôi chỉ thiếu một cái gì đó ở đây. – mutex

Các vấn đề liên quan