2013-05-22 2 views
7

Я не могу понять, как я могу позвонить в концентратор SignalR из WebAPI ApiController. Я собрал образец, который вы можете скачать here, что упрощает проблему и демонстрирует проблему.вызов концентратора SignalR из проблем контроллера WebAPI

  1. Я создал новый проект из шаблона ASP.NET MVC WebAPI.
  2. Я добавил новый концентратор SignalR в проект под названием ChatHub.
  3. Добавлена ​​HTML-страница, которая при загрузке подключается к ChatHub, присоединяется к группе и отправляет сообщение этой группе. Это отлично работает.
  4. На странице HTML также есть кнопка, которая при нажатии будет запускать вызов ajax методу почты ValuesController. В методе post ValuesController я хочу передать сообщение всем подключенным клиентам группы. Я не могу заставить это работать.

У меня есть простой концентратор 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 готов, как показано здесь.

<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 в методе 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"); 
    } 

Контакт-концентратор не работает. Ошибка не выбрасывается, но сообщение никогда не принимается. Также не работает установка точки останова в методе «Отправить» концентратора. Я чувствую, что делаю все правильно. Кто-нибудь поможет? Опять же, исходный код может быть найден here

ответ

14

Вы вызываете различные методы на клиенте:

контроллер API

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

Hub

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: Есть ли способ вызвать фактический метод ChatHub.Send из ApiController? Вышеупомянутый способ сделать это, по-видимому, обойти ChatHub и просто перейти прямо в контекст концентратора, чтобы сделать равноценным то, что делает ChatHub.Send, но что-то еще, что у меня есть в ChatHub.Send не будет запускаться \, нужно будет реплицировать в ApiController? Может быть, я просто что-то пропустил. – mutex