[asp.net]那么 SignalR 客户端不工作里面 AngularJs 控制器

发布时间: 2017/3/26 4:23:31
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我创建了基于路由的角应用。 如果不使用路由,那么 Signalr 工作正常,但工作时与路线,那么 Signalr 都只是一种方式从客户端到服务器。

<html ng-app="SignalR">
<head>
//Scripts
<script src="~/signalr/hubs"></script>
</head>
<body>
<a href="#/Today">Today</a>
<a href="#/History">History</a>

<div ng-view>
</div>

<script type="text/javascript">
    var hubConnetion = undefined;
    hubConnetion = $.connection.hubs;
    $.connection.hub.start();


    var SignalRControllers = angular.module('SignalRControllers', []);

    var SignalRApp = angular.module('SignalR', ['ngRoute', 'SignalRControllers']);


    SignalRApp.config(['$routeProvider',
      function ($routeProvider) {
          $routeProvider.
            when('/Today', {
                templateUrl: '@Url.Action("Today","Home")'
            }).
            when('/History', {
                templateUrl: '@Url.Action("History", "Home")'
            })
      }]);

</script>
<script src="~/AngularJs/TodayController.js"></script>
</body>
</html>

TodayController.js

SignalRControllers.controller('TodayController', ['$scope', '$http',
  function ($scope, $http) {

      $scope.sendTask = function () {
          hubConnetion.server.sendTask($("#taskName").val());//works
      }

      $scope.Task = "task1";
      hubConnetion.client.getTask= function (Task) {//never invoked
          $scope.Task = Task;
      }
  }]);

Today.html

<div ng-controller="TodayController">

    <div>{{Task}}</div>


    <input id="taskName" type="text" />
    <div ng-click="sendTask()">SendTask</div>

</div>

Hubs.cs

public class Hubs: Hub
{
   public void SendTask(string Name)
   {
      Clients.All.GetTask(Name);
   }
}

我不知道,但我认为,因为hubConnetion变量都包裹在控制器内,signlarR 找不到它。 有任何角的魔法,可以解决这个吗?

解决方法 1:

我也是相当新的那么 SignalR (和第一次使用的角),所以我重新创建 (简化) 项目在 ASP.NET MVC 4 (那么 SignalR 2.2),要把问题解决。我认为还有更多然后一...

1) 那么 SignalR 使用 JQuery。在 jQuery (和几乎任何其他 JS 框架) 其真的更好 '文件准备好了' 事件之后执行你的代码。所以我裹那么 SignalR 安装在 jQuery 文件准备好处理程序 (请参见下面的代码)。 此外我删除 hubConnetion 全局变量因为全局变量是坏 + 后环绕在 jQuery 文件准备好处理程序中,变量是本地到该处理程序和控制器代码中不能访问无论如何...

2)主要问题恕我直言,这是那么 SignalR 客户端 API的一部分)︰

通常你注册事件处理程序之前调用 start 方法来建立连接。如果你想要注册一些事件处理程序在建立连接之后,你能做到,但你必须注册至少一个您的事件处理程序调用 start 方法之前。原因之一是在应用程序中,可以有许多集线器,但你不会想要触发 OnConnected 事件每个集线器上的,如果你只打算使用到其中之一。当建立连接时,集线器的代理服务器上的客户端方法的存在是什么告诉那么 SignalR 来触发 OnConnected 事件。如果你不注册任何事件处理程序之前调用 start 方法,你将能够调用方法在集线器上,但是不会调用枢纽的 OnConnected 方法和没有客户端方法将调用从服务器

您的事件处理程序是安装在控制器的工厂方法,称为多后来连接 start() 方法。 尝试添加临时处理程序之前调用 start() 像这样︰

$.connection.tasklistHub.client.getTask = function () { };

3) 以确保问题是在那么 SignalR 和不具角,我开启了服务器和客户端侧跟踪。上述更改之后客户端成功地接收来自服务器的事件︰

SignalR: Triggering client hub event 'getTask' on hub 'TasklistHub'

但角未能更新 div 与接收到的数据。解决方法是使用 $rootScope.$apply 函数一起使用那么 SignalR 和角这篇文章所述。现在一切都按预期方式工作。请参阅下面的完整代码。

旁注︰ 我明白这是只是示例代码。在现实世界中的任何项目,我会考虑在某种形式的服务,如上文所述或使用此库(看上去很优雅) 的文章中的客户端上环绕那么 SignalR 集线器

我也收回我以前的答案,关于客户端处理程序名称作为同一文档中,客户端侧方法名称匹配是不区分大小写...

Index.cshtml

<html lang="en" ng-app="SignalR">
    <head>
        <meta charset="utf-8" />
        <title>SignalR & AngularJS</title>
        <script src="~/Scripts/jquery-1.6.4.js"></script>
        <script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
        <script src="~/signalr/hubs"></script>
        <script src="~/Scripts/angular.js"></script>

        <script type="text/javascript">
            $(function() {
                $.connection.hub.logging = true;

                // temporary handler to force SignalR to subscribe to server events
                $.connection.tasklistHub.client.getTask = function () { };

                $.connection.hub.start().done(function () {
                    $('#connectionStatus').text('Connected');
                    console.log('Now connected, connection ID =' + $.connection.hub.id);
                });
            });

            var SignalRControllers = angular.module('SignalRControllers', []);
            var SignalRApp = angular.module('SignalR', ['SignalRControllers']);
        </script>
        <script src="~/Scripts/app/TodayController.js"></script>
    </head>
<body>
    <div id="body">
        <div ng-view>
            <div ng-controller="TodayController">

                <div id="connectionStatus"></div>

                <div>{{Task}}</div>

                <input id="taskName" type="text"/>
                <input type="button" name="Send Task" value="Send Task" data-ng-click="sendTask()" />
            </div>
        </div>
    </div>
</body>
</html>

TodayController.js

SignalRControllers.controller('TodayController', [
        '$scope', '$http', '$rootScope',
        function ($scope, $http, $rootScope) {
            $scope.sendTask = function() {
                $.connection.tasklistHub.server.sendTask($("#taskName").val());
            };
            $scope.Task = "Empty";

            $.connection.tasklistHub.client.getTask = function (task) {
                console.log(task);
                $rootScope.$apply(function () {
                    $scope.Task = task;
                });             
            };
        }
    ]
);
赞助商