连接到信号集线器

Posted

技术标签:

【中文标题】连接到信号集线器【英文标题】:connect to signalr hub 【发布时间】:2014-08-31 12:55:00 【问题描述】:

我在控制台应用程序中创建了一个简单的 SignalR 集线器:

class Program

    static void Main(string[] args) 
        
        using (WebApp.Start<Startup>("http://localhost:1968"))
        
            Console.WriteLine("Server running!");        
            Console.ReadLine();    
         
     


public static class UserHandler

    public static HashSet<string> ConnectedIds = new HashSet<string>();


[HubName("echo")]
public class EchoHub : Hub 
 
    public void Say(string message) 
     
        Trace.WriteLine("hub: "+message);
        Clients.All.AddMessage(message);
    

    public override Task OnConnected()
    
        UserHandler.ConnectedIds.Add(Context.ConnectionId);
        return base.OnConnected();
    

    public override Task OnDisconnected()
    
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnected();
    


class Startup 
 
    public void Configuration(IAppBuilder app) 
     
        app.MapSignalR();
     
 

当我尝试从 Silverlight 应用程序连接它时,它会成功:

static Microsoft.AspNet.SignalR.Client.HubConnection signalR  get; set; 
public static Microsoft.AspNet.SignalR.Client.IHubProxy signalRhub  get; set; 

public static void StartSignalR()

    var url = "http://localhost:1968";
    signalR = new Microsoft.AspNet.SignalR.Client.HubConnection(url);
    signalR.Received += signalR_Received;
    signalRhub = signalR.CreateHubProxy("echo");
    signalR.Start().Wait();
    signalRhub.Invoke("Say", "hub invoked");

我的下一步是从 jquery 连接 SignalR 集线器:

<script src="../Scripts/jquery-1.6.4.js"></script>
<script src="../Scripts/jquery.signalR-2.1.0.js"></script>
<script>
    $(function ()
    
        var connection = $.hubConnection("http://localhost:1968");
        connection.start()
            .done(function () 
                console.log('connected');
                connection.send("success?");
            )
            .fail(function (a) 
                console.log('not connected'+a);
            );
    );
</script>

当我尝试运行这个脚本时,它给出了错误:

"XMLHttpRequest cannot load localhost:1968/signalr/negotiate?clientProtocol=1.4&_=1404978593482. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin <code>http://localhost:55282</code> is therefore not allowed access."

为什么我可以从我的 Silverlight 页面(托管在 localhost:3926)连接到集线器 并在我运行 jquery 脚本(托管在 localhost:55282)时失败?

如何才能在我的 jQuery 和 SignalR 集线器之间建立有效连接?

【问题讨论】:

我的猜测是这被解释为跨站点请求,因为 js 托管在与 SignalR 集线器不同的端口上。 Same Origin Policy 已生效。 这似乎是合理的,但为什么同样托管在不同端口上的 Silverlight 可以成功连接?如果是这样,是否可以设置 SignalR 集线器以允许交叉请求? Using CORS。浏览器是罪犯。在silverlight 实现中,您使用的是我认为的.NET SignalR 客户端? 您可以使用 jsonp,但我会将 SignalR 移至网络服务器 是的,我使用的是 .NET SignalR 客户端。 Vishal Ravlani 提供的解决方案似乎有效,感谢您的回答。 【参考方案1】:

改变

$(function ()
    
    var connection = $.hubConnection("http://localhost:1968");
    connection.start()
        .done(function () 
            console.log('connected');
            connection.send("success?");
        )
        .fail(function (a) 
            console.log('not connected'+a);
        );
);

$(function ()

var connection = $.hubConnection("http://localhost:1968");
var hub = connection.createHubProxy("echo");
hub.on("AddMessage", Method);
connection.start( jsonp: true )
            .done(function () 
            console.log('connected');
            hub.say("success?");
        )
        .fail(function (a) 
            console.log('not connected'+a);
        );
);

function Method(messageFromHub)

alert(messageFromHub);

class Startup 
 
    public void Configuration(IAppBuilder app) 
     
        app.MapSignalR();
     
 

class Startup 
 
    public void Configuration(IAppBuilder app) 
     
        app.MapSignalR(new HubConfiguration()  EnableJSONP = true ); 
 

应该可以。

app.MapSignalR(new HubConfiguration()  EnableJSONP = true ); 

connection.start( jsonp: true )

将允许跨站请求

【讨论】:

谢谢,它帮助我使用了 Web Api 和 php 客户端 我可以像 WPF 客户端一样引用这个吗?【参考方案2】:

使用 createHubProxy() 在 SignalR 中的服务器上进行 RPC:

感谢 Vishal Ravlani

的回答

但对我来说

hub.say("success?");

不起作用! (它对你有用吗?)

我必须写:

hub.invoke('say','success?');

而且 SignalR 已经在客户端自动检测到 CrossOrigin。

在我使用过的服务器上:

app.Map("/signalr", map =>
            
                map.UseCors(CorsOptions.AllowAll);

                map.RunSignalR();
            );

描述于:http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client#crossdomain

【讨论】:

据我所知,这不是一个答案吗?如果你有问题,你应该自己提出...... 这是对 Vishal Ravlanis 答案的补充。就我而言,这个答案并不完全有效。我的问题针对 Vishal Ravlanis... 1 @MichiBack hub.Invoke 也为我工作,而不是 hub.say

以上是关于连接到信号集线器的主要内容,如果未能解决你的问题,请参考以下文章

TCP/IP协议:网络设备

如何使用信号器允许 cors

获取连接到 SignalR 集线器的侦听器和客户端的数量

如何编写 Netty 客户端以连接到 Signalr 集线器?

从 SignalR .NET 客户端连接到工作集线器时出现 HttpClientException

如何从 iOS 上的 PhoneGap 应用程序连接到 SignalR 集线器?