22-Socket.IO和消息服务器
7.5.2 Socket.IO和消息服务器
当使用Socket.IO来对在客户端和服务器之间的消息进行路由时,我们创建的是一个消息服务器。消息服务器的另外一个例子是 Openfire,它使用 XMPP(Google Chat和Jabber使用的协议)来提供消息服务。消息服务器必须维护所有和客户端的连接,这样它们才能快速地接收和响应消息。它们也应该避免不需要的数据,从而把消息的大小减至最小。
传统的Web服务器,像Apache2,是比较弱的消息服务器,因为它们会为每个连接创建和分配一个进程(或者线程),并且只要连接保持着,进程就必须“活着”。你可能会猜到,在有了几百或者几千个连接之后,连接服务会消耗掉Web服务器的所有资源。Apache2从来都不是为此目的而设计的,它是作为内容服务器而被编写出来的,它的理念是在响应请求时,尽可能快地把数据推送出去,然后尽可能快地关闭连接。对于这些用途类型,Apache2是非常棒的选择,只要问问YouTube就知道了 [3]。
相比之下,Node.js是一个非常出色的消息服务器。由于它的事件模型(event model),它不会为每个连接创建一个进程。当打开或者关闭连接的时候,它会进行记录,在打开和关闭连接期间会做些维护工作。因此在一般的硬件上,它能够处理几万甚至几十万的并发连接。直到一个或者多个打开的连接发出了消息事件(比如请求或者响应),Node.js才会开始做重要的工作。
Node.js 能够处理的消息客户端的数量,取决于服务器实际承载的工作量。如果客户端相对空闲,服务器的任务就轻,可以应付很多的客户端。如果客户端繁忙,服务器的任务就重,能应付的客户端就要少很多。可以想像,在数据量很大的环境中,负载均衡(load balancer)会在提供消息通信的Node.js服务器集群之间、提供动态Web内容的Node.js服务器集群之间和提供静态内容的Apache2服务器集群之间“路由”流量。
使用Node.js比使用其他通信协议(像XMPP)有很多的好处。下面只列举了一些。
Socket.IO使得Web应用程序中的跨浏览器通信显得“微不足道”[4]。我们之前已经在产品级应用中使用过XMPP。相信我们:光为这软件就要花费很多的工作。
不用维护不同的服务器和配置。这又是一件大好事。
可以使用原生的JSON协议,而不是不同的语言。XMPP使用XML协议,并且需要复杂的软件对它进行编码和解码。
我们不用担心(至少是在初始阶段)可怕的、折磨其他消息通信平台的“同源”策略。如果内容不是来自JavaScript所在的相同服务器,则该浏览器策略就会阻止加载该内容 [5]。
现在我们来看一种Socket.IO的用途,这肯定能加深印象:动态单页应用。