【问题标题】:How to push data over the Internet?如何通过互联网推送数据?
【发布时间】:2009-11-29 12:14:31
【问题描述】:

我想将数据推送到客户端应用程序。客户端应用程序可以很厚也可以很薄。推动必须通过互联网进行。如何做到这一点?

编辑: 有没有一种方法可以让客户端应用程序打开与服务器的连接,让它在其生命周期内保持活动状态,然后继续通过该连接接收数据。我可以建造这样的东西吗?任何帮助表示赞赏。

更新:我的胖客户端将在 Wpf 中,而我的瘦客户端将是一个 silverlight 应用程序。我希望有最小的延迟。此外,对于某些类别的数据,更新频率将超过每秒 10 次。如果现成的东西不存在,我可以构建这样的解决方案。我只是想要一些指示/想法开始。

【问题讨论】:

  • 一定要推送吗?你能拉吗?它更容易......
  • @Dani:我想从服务器推送数据。
  • 能否举例说明每个方向的消息类型和大小?
  • 类型将是自定义类型,大小会有所不同,对于高频和低延迟的消息,最多 20 个字节,对于低频消息,最多为 100 个字节。

标签: c# .net wpf silverlight push


【解决方案1】:

如果您的客户端打开到服务器的套接字,它可以无限期地保持打开状态。只要确保每隔一段时间发送一些keepalive数据包即可。否则“智能”路由器可能会中断您的连接。

所以是的,可以做到!

【讨论】:

  • 是的,客户端可以创建套接字。但是可以保持连接打开 2 天左右吗?
  • 这是一个只有您或您的客户才能回答的问题。但从技术角度来看,让连接保持打开状态不会影响任何事情。
【解决方案2】:

您首先需要问自己几个问题:

  • 我的“客户端”是网络浏览器还是可执行文件?
  • 有多少客户端将连接到我的服务器?
  • 多久向客户端发送一次数据?
  • 客户端立即接收数据(而不是延迟一两秒)有多重要?

如果您的客户端是网络浏览器,那么您的选择会更加有限,请查看Comet 以获得一些指导。正如其他人提到的,这是good blog post explaining how to do Comet with ASP.NET

如果您不希望有很多客户端,那么打开从客户端到服务器的连接可能是一个可行的解决方案,请查看这些 MSDN 页面以获取信息和一个基本示例: - TcpListener - TcpClient

如果您期望有很多客户端(超过 50 个,具体取决于您的服务器硬件),那么您的选择取决于其他问题的答案:

如果您的客户端频繁获取数据并且可以接受短(秒)延迟,那么轮询是一个简单的解决方案,您可以对客户端隐藏实现,这样看起来数据正在被推送,但实际上在每隔几秒轮询一次的客户端。

如果您的客户不经常获取数据,那么 Comet 之类的内容可能是一个不错的选择,如果您正在寻找 .NET 解决方案,请搜索“Long Polling WCF”。

更新: 既然您现在已经声明您的客户是 Silverlight,我强烈推荐这些博客文章,谈谈您所追求的内容:

  • 使用套接字从服务器发送数据(hereherehere
  • 使用 WCF 双工服务发送数据(herehere

WCF 双工服务更好,因为它使用设置消息和响应,因此无需自己解析文本或二进制数据。它基本上是用于 Silverlight 的 Comet 版本。

【讨论】:

  • 拥有超过 50 个打开和等待到服务器的连接真的不是问题。即使是 5000 也不成问题。
  • @Timothy:谢谢你的回答。我有一个RIA。我想要最小的延迟,并且服务器对某些类别的数据的推送也会很频繁。如果有帮助的话,我已经准备好采用本土解决方案了。
  • @reinier:这取决于 :) 如果我们谈论的是打开连接,每个连接都有一个 TcpListener 以及可能与每个侦听器关联的其他数据,那么它可能很快就会对服务器造成负担,是的一些配置如果设计好并且硬件可以支持它,则可以处理数千个连接。
  • @PK:在这种情况下,我建议使用 TcpClient 和 TcpListener 组合一个快速原型应用程序,并使用代表您希望查看的数量是否满足您的需求的模拟数据。如果我有时间,我可能会使用一些示例代码发布针对该解决方案的另一个答案。
【解决方案3】:

简短的回答是使用轮询。

这个问题很相似:

asp.net http server push to client

【讨论】:

  • 有没有办法避免轮询?
  • kragen:这个问题不相似......这个问题不是专门针对网络服务器,而是关于一般的“服务器”
【解决方案4】:

我建议你使用Comet。查看以下articleexample

【讨论】:

  • 问题并没有说要使用网络服务器。如果不需要网络服务器,那么彗星是个坏主意
【解决方案5】:

今年早些时候我需要这样做,但我在这台计算机上找不到代码。这SO link 有帮助吗?

更新:我找到了我在需要时使用的the article。警告它使用 3.5,我认为是 WCF。此处代码从 Keyvan Nayyeri 的文章中复制:

        OperationContext context = OperationContext.Current;
        MessageProperties messageProperties = context.IncomingMessageProperties;
        RemoteEndpointMessageProperty endpointProperty =
            messageProperties[RemoteEndpointMessageProperty.Name]
            as RemoteEndpointMessageProperty;

        return string.Format("Hello {0}! Your IP address is {1} and your port is {2}",
            value, endpointProperty.Address, endpointProperty.Port);

【讨论】:

    【解决方案6】:

    您最好的解决方案是像 Kragen 建议的那样使用轮询,它可以确保您的服务器不会因为只在极少数情况下发送数据而存在的空闲会话而陷入困境。轮询为您提供了相同的功能,但是您的服务器上没有持续的负载,除了每个客户端需要一个线程(假设您的服务器为每个客户端生成一个线程,如 apache 等)。使用瘦客户端(在浏览器中运行),您可以使用 AJAX 来防止页面不断重新加载。如果在胖客户端中,您可以做同样的事情,但使用后台定时事件来发送请求。

    如果您仍然需要在胖客户端场景中将数据从服务器推送到客户端,最好的解决方案是让客户端打开一个监听套接字,当需要将来自服务器的请求推送到客户端时,服务器连接到客户端并发送请求(经过身份验证,服务器记录用户 IP 以启动连接)。在瘦客户端场景(通过 Web 浏览器)中,如果不是不可能的话(当使用适当的安全策略时),这将非常难以做到。

    我们会建议您更详细地解释您为什么要这样做,这将使我们能够为您提供更“有针对性”的解决方案,以满足您的需求。

    【讨论】:

    • 让客户端打开一个监听套接字不是一个好主意。通常客户端在防火墙后面,服务器无法联系服务器。最好让客户端发起连接。
    • 您是 100% 正确的,但是正如您在描述中看到的那样,如果他必须在没有活动会话的情况下将数据从服务器发送到客户端,那么他需要拥有 FatClient 应用程序打开一个端口来监听。
    【解决方案7】:

    有很多方法 - 最好的方法 - 让客户端检查服务器的更新,并让它拉数据(使用标准 ftp 协议 - 用于文件或其他通信协议 - 如 WCF、Web服务等) 这样您就无需担心防火墙和 nat。

    查看您的评论 - 这会很困难,好像客户端在 nat 后面,没有静态路由是不可能的 - 所以如果这可能是您的情况,您不能推送...您必须从客户端。

    【讨论】:

    • 您是认真地建议使用 FTP 从服务器获取数据到客户端吗?这将如何处理可能每秒更新多达 10 次的“事物”?他是否应该继续重新获取相同的文件,然后每次都加载/反序列化文件?如果他要这样做,那么为什么不使用 WCF 来发送对象而不是文件呢?
    • 我不确定这个问题是指小块数据(如对象)还是客户端更新文件等。 ftp 是一种方式——如果要推送文件,WCF 是对象的首选。主要的答案想法是转向投票而不是推送。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2012-01-06
    • 2011-07-04
    相关资源
    最近更新 更多