Web 套接字服务器端处理模型 [英] Web sockets server side processing model

查看:25
本文介绍了Web 套接字服务器端处理模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要使用网络套接字实现支持客户端的服务器,服务器是否与每个客户?这如何扩展?

To implement a server supporting clients using web sockets, do servers keep an open HTTP connection with each client? How can this scale?

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

What are the "programming models" when implementing this type of server? Ie: most web apps have servlets, etc which support a connect->request->response->close type model. Whereas with web sockets the connect stays open indefinitely.

推荐答案

您通常需要在 异步 模型使这些长期连接正常工作.有几种不同的技术可以进行异步 I/O;所有这些都有其优点和缺点.

You generally need to work in an asynchronous model for these long-lived connections to work. There are several different techniques for doing asynchronous I/O; all of which have their advantages and disadvantages.

任何使用过 JavaScript 和 AJAX 是回调模型;您在其中发送请求,并安装一个回调以在完成时调用.这就是 XMLHTTPRequest 的工作原理,在等待页面请求完成时不会阻塞所有其他页面.这也是 Twisted Python 网络框架的工作方式,尽管它可以调用对象上的方法或回调函数,具体取决于您使用的接口.

One which should already be familiar to anyone who has worked with JavaScript and AJAX is the callback model; in which you send a request, and install a callback to be called when it completes. This is how XMLHTTPRequest works, without blocking all of the other pages while they wait for one page's request to finish. This is also how the Twisted Python networking framework works, though it can call methods on objects or callback functions depending on the interfaces you use.

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

Another powerful model is the Erlang style approach, called the Actor model, has many, many lightweight processes (like threads, but with no shared state), each of which communicate with each other via asynchronous messages. The Erlang runtime has been implemented to make spawning thousands of processes very efficient; then you can just have one process for each connection, and have them send messages to other processes implementing the backend of your application. Erlang processes can also be automatically scheduled on multiple OS threads, to take full advantage of multi-core systems. ejabberd, a popular Jabber server (a chat protocol, which requires many long-lived open connections), is implemented in Erlang, as is the Facebook Chat system.

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

The new Go language from Google uses a similar approach, closer to Hoare's Communicating Sequential than Erlang's Actor model, but which has a lot of similarities.

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

In Mac OS X 10.6, Apple introduced Grand Central Dispatch, along with blocks (essentially closures) in C, C++, and Objective-C. This allows something like the AJAX or Twisted style event driven callback model, but with explicitly managed queues that are executed sequentially to manage access to shared resources in a multithreaded, multi-core environment. Twisted and JavaScript both run single threaded, and so can only take advantage of a single core, unless you use multiple operating system processes, which can be fairly heavy weight and increase the costs of communication between them.

然后是更传统的模型,比如 Unix select 函数,或者更现代和更强大的epollkqueue().在这些中,您的程序中通常有一个主循环,它设置了一堆要监视的事件(网络 I/O 返回更多数据,文件 I/O 返回更多数据,建立新的网络连接等),然后调用一个系统调用,在这些事件之一发生之前​​阻塞,此时您检查发生了哪个事件,然后适当地处理它.这些系统调用通常用于提供上述更高级别的框架.

Then there are the more traditional models, like the Unix select function, or the more modern and capable epoll or kqueue(). In these, you generally have a main loop in your program, which sets up a bunch of events to watch for (network I/O returns some more data, file I/O returns more data, a new network connection is made, etc), and then calls a system call that blocks until one of those events has occurred, at which point you check which one has occurred and then handle it appropriately. These system calls are generally used to provide the higher-level frameworks described above.

有关令人震惊的一系列可用选项的非常好的概述(侧重于更传统和更低级别的 Unix 方法),请参阅 C10K 问题,对有助于同时处理 10,000 个同时连接的不同技术的调查.这也有一个很好的 C 和 C++ 库列表,用于抽象各种可用的 API,例如 libevent.

For a very good overview of the staggering array of options available (focusing on the more traditional, and lower level, Unix approaches), see The C10K Problem, a survey of different techniques for helping to deal with 10,000 simultaneous connections at once. This also has a good list of C and C++ libraries for abstracting over the various APIs available, such as libevent.

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

A final option, of course, is to use one process or one OS thread for each connection. The problem is, processes are very heavy weight, and even threads are fairly heavy weight compared to many of these options. In general, for the best performance, you would want to have one process or thread per CPU, each using an asynchronous I/O API to figure out when it needs to do work, and then dispatching that work to one of several objects or callbacks that have been registered to handle connections, or one of several Erlang style lightweight processes that is waiting for a message, or something of the sort.

作为旁注,网络套接字中的连接不是 HTTP 连接,而是一种新协议,websocket 协议,尽管您可以使用与 HTTP 相同的端口,并将 HTTP 连接升级为 Web 套接字以兼容现有的防火墙规则.

As a side note, the connection in web sockets are not HTTP connections, but a new protocol, the websocket protocol, though you can use the same port as HTTP, and upgrade an HTTP connection to a web socket in order to be compatible with existing firewall rules.

这篇关于Web 套接字服务器端处理模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆