2013-05-22 12 views
7

Non riesco a capire come posso chiamare un hub SignalR da un API AAPController WebAPI. Ho messo insieme un esempio che è possibile scaricare here che semplifica il problema e dimostra il problema.chiama l'hub SignalR dai problemi del controller WebAPI

  1. Ho creato un nuovo progetto dal modello WebAPI di ASP.NET MVC.
  2. Ho aggiunto un nuovo Hub SignalR al progetto chiamato ChatHub.
  3. Aggiunta una pagina HTML che si carica, si connette a ChatHub, si unisce a un gruppo e invia un messaggio a quel gruppo. Funziona alla grande
  4. La pagina HTML ha anche un pulsante che quando viene fatto clic attiva una chiamata ajax al metodo Post di ValuesController. Nel metodo post di ValuesController, voglio trasmettere un messaggio a tutti i client connessi del gruppo. Non riesco a farlo funzionare.

Ho un hub SignalR semplice con solo 2 metodi.

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

ho creato una pagina HTML molto semplice che si connette al mozzo Chat quando il DOM è pronto, come mostrato qui.

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

Niente di speciale. Ogni volta che l'hub connesso riceve un nuovo messaggio, un nuovo elemento viene aggiunto all'elenco non ordinato. C'è un pulsante che effettua una chiamata Ajax nel metodo del 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"); 
    } 

La chiamata hub non funziona. Non viene generato un errore, ma il messaggio non viene mai ricevuto. Anche l'inserimento di un punto di interruzione nel metodo "Invia" dell'hub non funziona. Sento che sto facendo bene. Qualcuno aiuto? Anche in questo caso, il codice sorgente può essere trovato here

risposta

14

si sta chiamando diversi metodi sul client:

regolatore API

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

Hub

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

Il metodo che si desidera chiamare è newMessage non inviare

chat.client.newMessage = onNewMessage; 
+0

David, grazie mille. Quindi appare sul server, posso chiamare qualsiasi metodo off di hubContext.Clients.Group ("TestGroup") come hubContext.Clients.Group ("TestGroup"). HelloNasty e il client sarà automagicamente in grado di rispondere a quello stesso metodo inventato Pazzo. Ho bisogno di studiare le capacità dinamiche di C# :-) – DapperDanh

+0

Questo è il punto :) – davidfowl

+0

@dfowler: C'è un modo per chiamare il metodo ChatHub.Send effettivo da ApiController? Il modo sopra descritto per farlo sembra aggirare ChatHub e andare direttamente al contesto dell'hub per fare l'equivalente di ciò che fa ChatHub.Send - ma qualsiasi altra cosa che ho in ChatHub.Send non verrà eseguita \ avrebbe bisogno di essere replicata nel ApiController? Forse mi manca qualcosa qui. – mutex

Problemi correlati