WebSocket和Socket.IO

下面是一些有用的链接:

WebSocket的诞生源于在Web端上做实时应用的需求。在实现技术上有这么几种:

所以如果没有特殊情况的话,应该尽可能地使用socket.io而不是websocket. 我同时尝试过 websocketsocket.io, socket.io实现起来容易太多了。具体来说, socket.io里面有这么几点特性:

  1. namespace. 可以把namespace当做一个房间来理解。理论上一个连接可以关联到多个namespace, server可以给某个namespace下面所有的连接发送消息。
  2. event. event可以用于区分不同的消息类型,不同的消息类型关联不同格式的数据
  3. 支持message queue. 这点对水平扩展很有用。一个server只能管理和这个server连接的clients, 如果需要群发消息的话可能会设计到多个servers. 我们可以将这些servers subscribe到某个message queue上,然后往这个message queue上写入消息,就可以通知到所有的servers了。

使用socket.io的时候,我尝试了一下压力测试,两个指标:创建连接的延迟以及接收消息的延迟。需要注意的是创建连接(销毁连接)必须控制并发数,否则server没有响应那么连接之后的握手通常就会失败。测试代码可以看 这里.

运行脚本如下 `(venv) [ec2-user@us_ws0 ~]$ ./load_client.py –port 12307 –bind 192.168.77.10,192.168.77.11,192.168.77.12,192.168.77.13 –batch-round 10 –batch-size 500 –workers 2`

这样计算下来,每个网卡对应 5000 * 2 = 1w个连接,一共4w个连接。

实际观察到创建了16w个链接,这个是因为client端会创建两个连接(这个似乎是python socket.io client的问题,我没有办法正确地使用默认的namespace).

UPDATE@2018-02: 在load_client.py里面需要主动地调用connect(path = '/')接口

(venv) [ec2-user@us_ws0 ~]$ ss -s
Total: 160607 (kernel 0)
TCP:   160106 (estab 160084, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6
 *         0         -         -
RAW       0         0         0
UDP       12        8         4
TCP       160106    160102    4
INET      160118    160110    8
FRAG      0         0         0

整个运行期间输出的完成日志可以看 bench.output.