Web套接字服务器端处理模型
要使用Web套接字实现支持客户端的服务器,服务器是否与每个客户端保持开放的HTTP连接? 这如何扩展?
在实施这种类型的服务器时,什么是“编程模型”? 也就是说:大多数Web应用程序都有支持connect-> request-> response-> close类型的servlet等。 而使用网络套接字时,连接保持无限期打开状态。
您通常需要使用异步模型来处理这些长期存在的连接。 有几种不同的技术来完成异步I / O; 所有这些都有其优点和缺点。
任何使用JavaScript和AJAX的人都应该已经熟悉它了,它是回调模型; 在其中发送一个请求,并安装一个回调,当它完成时被调用。 这就是XMLHTTPRequest
工作原理,在等待一个页面的请求完成时不会阻塞所有其他页面。 这也是Twisted Python网络框架的工作原理,但它可以根据您使用的接口调用对象上的方法或回调函数。
另一个强大的模型是Erlang风格的方法,称为Actor模型,有很多很多轻量级进程(像线程但没有共享状态),每个进程通过异步消息相互通信。 Erlang运行时已经实现,可以产生数千个非常高效的进程; 那么您可以为每个连接创建一个进程,并让他们将消息发送到实现应用程序后端的其他进程。 Erlang进程也可以在多个OS线程上自动调度,以充分利用多核系统。 ejabberd是一款流行的Jabber服务器(一种聊天协议,它需要许多长期的开放式连接),与Facebook聊天系统一样,在Erlang中实现。
来自Google的新Go语言使用类似的方法,与Erlang的Actor模型相比更接近Hoare的通信顺序,但它有很多相似之处。
在Mac OS X 10.6中,Apple引入了Grand Central Dispatch,以及C,C ++和Objective-C中的块(基本上是闭包)。 这允许类似于AJAX或Twisted风格的事件驱动回调模型,但具有按顺序执行的显式管理队列,以管理对多线程多核环境中共享资源的访问。 Twisted和JavaScript都运行单线程,因此只能利用单个内核,除非使用多个操作系统进程,这些进程可能相当重,并增加了它们之间的通信成本。
然后是更传统的模式,比如Unix select
功能,或者更现代化和更强大的epoll
或kqueue()
。 在这些应用程序中,通常在程序中有一个主循环,它建立了一系列需要监视的事件(网络I / O返回更多数据,文件I / O返回更多数据,创建新的网络连接等) ,然后调用阻塞的系统调用,直到其中一个事件发生,此时您检查发生了哪一个事件,然后进行适当的处理。 这些系统调用通常用于提供上述更高级别的框架。
有关可用选项的惊人选择(侧重于更传统的和更低级别的Unix方法)的非常好的概述,请参阅C10K问题,这是一种帮助同时处理10,000个同时连接的不同技术调查。 这也有一个很好的C和C ++库列表,用于抽象各种可用的API,比如libevent。
当然,最后的选择是为每个连接使用一个进程或一个OS线程。 问题是,过程的重量非常重,甚至与许多这些选项相比,线程的重量也相当重。 通常,为了获得最佳性能,您希望每个CPU都有一个进程或线程,每个都使用异步I / O API来确定何时需要执行工作,然后将该工作分派到多个对象或回调中的一个已经被注册来处理连接,或者正在等待消息的几个Erlang样式的轻量级进程之一,或者类似的东西。
请注意,Web套接字中的连接不是HTTP连接,而是一种新协议,websocket协议,尽管您可以使用与HTTP相同的端口,并且将HTTP连接升级到Web套接字以便与现有的防火墙规则。
一般来说,您应该期望使用WebSockets以及旨在以轻量级方式处理负载的自定义服务器实现。 这种服务器已经存在用于长期COMET连接等等。
它与http的不同之处在于每个后续的请求/响应不需要被包装在带有http头的http消息中。 所以实时应用程序不需要解析标题的开销。 在最初的类似于http的握手之后,它基本上像普通的ol'tcp套接字一样。
这可以用servlet来模拟,但是人们只需要区分初始请求(包含所有头文件)和随后的双向对话框,其大部分格式是任意的。
链接地址: http://www.djcxy.com/p/44711.html