SignalR:为啥选择集线器与持久连接?

Posted

技术标签:

【中文标题】SignalR:为啥选择集线器与持久连接?【英文标题】:SignalR: Why choose Hub vs. Persistent Connection?SignalR:为什么选择集线器与持久连接? 【发布时间】:2012-03-06 00:47:56 【问题描述】:

我最近一直在搜索和阅读 SignalR,虽然我看到很多关于集线器和持久连接之间区别的解释,但我无法理解下一个级别,即为什么我会选择一种方法而不是另一种方法?

【问题讨论】:

【参考方案1】:

从我在Connection and Hubs section 中看到的内容看来,Hub 似乎提供了一个覆盖较低级别持久连接的主题系统。

来自下面高度赞成的评论:

部分正确。您也可以在持久连接中获取主题或组。最大的区别在于发送不同类型的消息。例如,您有不同类型的消息,并且您想要发送不同类型的有效负载。使用持久连接,您必须将消息类型嵌入到负载中(请参阅原始示例),但集线器使您能够通过连接执行 RPC(允许您从服务器和从服务器到客户端调用客户端上的方法) .另一件大事是模型绑定。集线器允许您将强类型参数传递给方法。

文档中使用的示例使用了聊天室的比喻,用户可以加入特定的房间,然后只能从同一房间的其他用户那里获得消息。更一般地,您的代码订阅一个主题,然后只获取发布到该主题的消息。通过持久连接,您将获得所有消息。

您可以轻松地在持久连接之上构建自己的主题系统,但在这种情况下,SignalR 团队已经为您完成了这项工作。

【讨论】:

部分正确。您也可以在持久连接中获取主题或组。最大的区别在于发送不同类型的消息。例如,您有不同类型的消息,并且您想要发送不同类型的有效负载。使用持久连接,您必须将消息类型嵌入到负载中(请参阅原始示例),但集线器使您能够通过连接执行 RPC(允许您从服务器和从服务器到客户端调用客户端上的方法) .另一件大事是模型绑定。集线器允许您将强类型参数传递给方法。 好点@davidfowl - 我已将您的评论复制到答案中,因为我认为它应该更突出。【参考方案2】:

有两种使用 SignalR 的方法:您可以通过覆盖它的 PersistentConnection 类在低级别访问它,这使您可以对它进行大量控制;或者您可以让 SignalR 使用高级“集线器”为您完成所有繁重的工作。

【讨论】:

【参考方案3】:

Persistent Connection 是一个较低级别的 API,您可以在连接打开或关闭时在更具体的时间执行操作,在大多数应用程序中 Hub 是最佳选择

【讨论】:

【参考方案4】:

主要区别在于你不能用 PersistentConnection 做 RPC,你只能发送原始数据。所以不要像这样从服务器发送消息

Clients.All.addNewMessageToPage(name, message);

您必须使用Connection.Broadcast()Connection.Send() 发送一个对象,然后客户端必须决定如何处理它。例如,您可以发送这样的对象:

Connection.Broadcast(new 
    method: "addNewMessageToPage",
    name: "Albert",
    message: "Hello"
);

在客户端,而不是简单地定义

yourHub.client.addNewMessageToPage = function(name, message)  
    // things and stuff
;

你必须添加一个回调来处理所有传入的消息:

function addNewMessageToPage(name, message) 
    // things and stuff


connection.received(function (data) 
    var method = data.method;

    window[method](data.name, data.message);
);

您必须在OnReceived 方法中在服务器端执行相同类型的调度。您还必须在那里反序列化数据字符串,而不是像使用 hub 方法那样接收强类型对象。

选择 PersistentConnection 而不是 Hubs 的理由并不多。我知道的一个原因是可以通过 PersistentConnection 访问send preserialized JSON,而使用集线器则无法做到这一点。在某些情况下,这可能是相关的性能优势。

除此之外,请参阅documentation 的这句话:

选择沟通模式

大多数应用程序都应该使用 Hubs API。 Connections API 可以 在以下情况下使用:

需要指定实际发送消息的格式。

开发人员更喜欢使用消息传递和调度模型 而不是远程调用模型。

正在移植使用消息传递模型的现有应用程序以使用 SignalR。

根据您的消息结构,您还可能从使用 PersistentConnection 中获得小的性能优势。

您可能想查看 SignalR 示例,特别是 this here.

【讨论】:

我的一位同事对我说,他选择 PersistentConnection 而不是 Hubs 的原因是安全原因,Hubs 中是否存在任何安全问题?【参考方案5】:

比较这两者时要考虑三个要点:

消息格式 通信模型 SignalR 自定义

使用集线器的消息格式基本上由您处理,但使用持久连接,消息是原始的,并且已经被标记化并来回解析。如果消息大小很重要,那么还要注意持久连接的负载远小于集线器的负载。

在通信模型方面,持久连接基本上具有发送和接收消息的功能,而集线器采用remote procedure call 模型,根据要求具有独特的功能。

在自定义方面,由于持久连接的级别较低,因此您可以更好地控制自定义。

【讨论】:

以上是关于SignalR:为啥选择集线器与持久连接?的主要内容,如果未能解决你的问题,请参考以下文章

SignalR入门之持久性连接

如何使用signalr实现离线聊天

asp.net signalR 专题—— 第二篇 对PersistentConnection持久连接的快速讲解

为啥多次收到此 SignalR 消息?

如何确定与 SignalR 客户端的服务器断开连接?

使用 SignalR 集线器向特定连接用户广播消息