从WebAPI控制器问题调用SignalR集线器

时间:2013-05-22 15:36:57

标签: c# signalr

我无法弄清楚如何通过WebAPI ApiController调用SignalR集线器。我已经汇总了您可以下载here的示例,该示例可以简化问题并演示问题。

  1. 我从ASP.NET MVC WebAPI模板创建了一个新项目。
  2. 我在名为ChatHub的项目中添加了一个新的SignalR Hub。
  3. 添加了一个HTML页面,该页面在加载时连接到ChatHub,加入组并向该组发送消息。这很棒。
  4. HTML页面还有一个按钮,单击该按钮将触发对ValuesController的post方法的ajax调用。在ValuesController的post方法中,我想向组中所有连接的客户端广播一条消息。我不能让这个工作。
  5. 我有一个简单的SignalR集线器,只有两种方法。

    [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中心,如下所示。

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

    没什么特别的。每当连接的集线器收到新消息时,都会将新项添加到无序列表中。有一个按钮可以对ValuesController post方法进行Ajax调用。

    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呼叫不起作用。不会抛出错误,但是,永远不会收到消息。在Hub的“Send”方法中设置断点也不起作用。我觉得我做得对。有人帮吗?同样,可以找到源代码here

1 个答案:

答案 0 :(得分:15)

您在客户端上调用不同的方法:

API控制器

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

集线器

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

您要调用的方法是newMessage not send

chat.client.newMessage = onNewMessage;