使用以下方法实现支持客户端的服务器 网络套接字, ,服务器是否与每个客户端保持开放的 HTTP 连接?这个规模如何实现?

实现此类服务器时的“编程模型”是什么?IE:大多数网络应用程序都有 servlet 等,它们支持连接->请求->响应->关闭类型模型。而使用网络套接字时,连接会无限期地保持打开状态。

有帮助吗?

解决方案

您通常需要在 异步 这些长期连接发挥作用的模型。有多种不同的技术可用于执行异步 I/O;所有这些都有其优点和缺点。

任何使用过 JavaScript 的人都应该熟悉这一点 阿贾克斯 是回调模型;您可以在其中发送请求,并安装一个回调,以便在请求完成时调用。就是这样 XMLHTTPRequest 有效,在等待某一页面的请求完成时不会阻塞所有其他页面。这也是如何 扭曲的 Python 网络框架可以工作,但它可以根据您使用的接口调用对象方法或回调函数。

另一个强大的模型是 埃尔兰 称为 Actor 模型的风格方法有很多很多轻量级进程(如线程,但没有共享状态),每个进程都通过异步消息相互通信。Erlang 运行时的实现可以非常高效地生成数千个进程;那么您可以为每个连接设置一个进程,并让它们向实现应用程序后端的其他进程发送消息。Erlang 进程还可以自动调度到多个操作系统线程上,以充分利用多核系统。 埃贾伯德, ,一个流行的 Jabber 服务器(一种聊天协议,需要许多长期开放的连接),是在 Erlang 中实现的,就像 脸书聊天系统.

新的 Go语言 来自 Google 的使用了类似的方法,比 Erlang 的 Actor 模型更接近 Hoare 的 Communicating Sequential,但有很多相似之处。

在 Mac OS X 10.6 中,Apple 引入了 大中央快讯, ,以及 C、C++ 和 Objective-C 中的块(本质上是闭包)。这允许类似 AJAX 或 Twisted 风格的事件驱动回调模型,但具有显式管理的队列,这些队列按顺序执行以管理对多线程、多核环境中共享资源的访问。Twisted 和 JavaScript 都运行单线程,因此只能利用单核,除非您使用多个操作系统进程,这可能相当重并增加它们之间的通信成本。

然后还有更传统的模型,比如 Unix select 功能,或者更现代、更有能力的 epoll 或者 kqueue(). 。在这些中,您的程序中通常有一个主循环,它设置了一堆要监视的事件(网络 I/O 返回更多数据,文件 I/O 返回更多数据,建立新的网络连接等) ,然后调用一个系统调用,该系统调用会阻塞,直到发生其中一个事件,此时您检查发生了哪一个事件,然后进行适当的处​​理。这些系统调用通常用于提供上述更高级别的框架。

有关可用选项的令人惊叹的数组的非常好的概述(重点关注更传统的、较低级别的 Unix 方法),请参阅 C10K 问题, ,对有助于同时处理 10,000 个并发连接的不同技术的调查。它还提供了一个很好的 C 和 C++ 库列表,用于抽象各种可用的 API,例如 自由事件.

当然,最后一种选择是为每个连接使用一个进程或一个操作系统线程。问题是,与许多这些选项相比,进程的重量非常重,甚至线程的重量也相当重。一般来说,为了获得最佳性能,您希望每个 CPU 有一个进程或线程,每个进程或线程都使用异步 I/O API 来确定何时需要执行工作,然后将该工作分派给多个对象或回调之一已注册来处理连接,或正在等待消息的几个 Erlang 风格的轻量级进程之一,或类似的东西。

顺便说明一下,Web 套接字中的连接不是 HTTP 连接,而是一种新协议,即 网络套接字协议, ,尽管您可以使用与 HTTP 相同的端口,并将 HTTP 连接升级到 Web 套接字,以便与现有的防火墙规则兼容。

其他提示

一般来说,你应该会使用WebSockets与定制服务器实现设计来处理一个轻量级的方式负载。这样的服务器已经存在长寿命COMET连接等。

它从http不同之处在于每个后续请求/响应不需要被包裹在HTTP消息与HTTP标头。所以实时应用程序不需要解析报头的开销。后初始HTTP状握手,它主要表现像一个普通的醇” TCP套接字。

此可以使用servlet建模,但人们会只需要初始请求之间进行区分(与所有标头)和随后的2路对话框,其格式是任意的大部分。

看一看在HTML Web服务器旋风实现5周的WebSockets: http://bret.appspot.com/entry/web-sockets-in-龙卷风

我还没有与该模块还起到,尽管

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top