没有从 SignalR 跨域返回消息,但 ping 工作正常

Getting no messages back from SignalR cross domains, but ping working

我参考了我之前的一个 post,在那里我得到了一些帮助连接到 SignalR 跨域 and I used This 示例来构建我的 POC。但是,我使用的示例是单个

我仍在努力弄清楚 SignalR 的魔力是如何工作的,我想我了解其中的大部分内容,但不知何故我无法让它发挥作用。我的代码可以很好地连接到集线器,如果我让它保持打开状态,我将继续从发送的 ping 中获取 pong 结果。

但是,我的集线器似乎没有任何响应。这是我所有的代码,希望有人能指出我正确的方向:

Startup.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        .
        .
        .

        app.UseCors(_CorsOptions.Value);

        // Branch the pipeline here for requests that start with "/signalr"
        app.Map("/signalr", map =>
        {
            map.RunSignalR(new HubConfiguration { EnableDetailedErrors = true });
        });
    }

    private static Lazy<CorsOptions> _CorsOptions = new Lazy<CorsOptions>(() =>
    {
        return new CorsOptions
        {
            PolicyProvider = new CorsPolicyProvider
            {
                PolicyResolver = context =>
                {
                    var policy = new CorsPolicy();

                    foreach (string allowedCOrsOrigin in ConfigurationManager.AppSettings["AllowedCORS-Origins"].Split(',').ToArray())
                    {
                        if(!string.IsNullOrEmpty(allowedCOrsOrigin) && !policy.Origins.Contains(allowedCOrsOrigin))
                        {
                            policy.Origins.Add(allowedCOrsOrigin);
                        }
                    }

                    policy.AllowAnyMethod = true;
                    policy.AllowAnyHeader = true;
                    policy.SupportsCredentials = true;
                    return Task.FromResult(policy);
                }
            }
        };
    });
}

_SignalBase.cs:

public abstract class _SignalRBase<THub> : ApiController where THub : IHub
{
    private readonly Lazy<IHubContext> _hub = new Lazy<IHubContext>(
        () => GlobalHost.ConnectionManager.GetHubContext<THub>()
    );

    protected IHubContext Hub
    {
        get { return _hub.Value; }
    }
}

FooHub.cs:

[HubName("foos")]
public class FooHub : Hub { }

FooController.cs:

[RoutePrefix("api/foo")]
public class FooController : _SignalRBase<FooHub>
{
    public IHttpActionResult Bar(FooDTO foo)
    {
        // notify all connected clients            
        Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<FooHub>()
            .Clients.All.newFoo(foo);

        return Ok(foo);
    }
}

FooDTO.cs:

public class FooDTO
{
    public int First { get; set; }

    public int Second { get; set; }
}

Sender.html

<div class="container">
    <div class="row">
        <div class="col-md-12">
            <button type="button" ng-click="DoSignalR()" ></button>
        </div>
    </div>
</div>

<!-- Reference the autogenerated SignalR hub script -->
<script src="//localhost:31374/signalr/hubs"></script>

Receiver.html:

<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div>
                <ul>
                    <li ng-repeat="foo in receivedFoos">
                        Foo {{foo.First}} &amp; {{foo.Second}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>

<!-- Reference the autogenerated SignalR hub script -->
<script src="//localhost:31374/signalr/hubs"></script>

Angular 控制器:

.controller('SignalRCtrl', function ($scope, TESTSignalR, $rootScope) {    
    $scope.receivedFoos = [];

    var newFoo = function(data) {
        console.log("newFoo function");
        $scope.$apply(function () {
            $scope.receivedFoos.push(data);
        });
    };

    TESTSignalR.initialize(newFoo);

    //  Sender    
    $scope.DoSignalR = function() {        
        var FooDTO = {
            "First": 1234,
            "Second": 3456
        };

        TESTSignalR.DoSignalR(FooDTO);
    };
})

Angular 服务:

.factory('TESTSignalR', function($http, APIPath, $rootScope) {    
    var proxy = null;

    var initialize = function (callback) {

        // fetch connection object and create proxy
        var connection = $.hubConnection();
        this.proxy = connection.createHubProxy('foos');

        $.connection.hub.url = "http://localhost:31374/signalr";

        // start connection
        $.connection.hub.start({ xdomain: true })
            .done(function () {
                console.log('Connected to signalR. connectionId : ' + $.connection.hub.id); 
            })
            .fail(function () {
                console.log('Could not connect to signalR!');
            });

        var hubConnection = $.connection.foos;

        hubConnection.client.newFoo = function(data) {
            callback(data);
        };
    };

    var DoSignalR = function (foo) {
        var url = "http://localhost:31374/api/foo/bar";

        $http.post(url, foo)
        .success(function(response) {
            console.log(response);
        })
        .error(function(error) {
        console.log(error);
        });
    }

    return {
        initialize: initialize,
        DoSignalR: DoSignalR
    };
})

编辑:我更新了上面的代码以反映@Sal-Niro 指出的最新变化。现在应该一切正常

您似乎正试图在 FooController 的上下文中调用 Hub 方法,为此您将进行稍微不同的调用。为什么要从控制器执行此操作而不是从客户端调用服务器集线器方法?如果需要从控制器调用,请尝试以下方法

[RoutePrefix("api/foo")]
public class FooController : ApiController
{
    public IHttpActionResult Bar(FooDTO foo)
    {
        // notify all connected clients
        GolbalHost.ConnectionManager.GetHubContext<FooHub>().Clients.All.newFoo(foo);

        return Ok(foo);
    }
}

您也可能没有将您的代理完全正确地引用到您的 [HubName("foos")] 集线器。观察您对 newFoo 的实施,尝试以下

var hubConnection = $.connection.foos; 

hubConnection.client.newFoo = function(data) {
    // data
}