瞬时套接字和持久套接字
在传统网络编程中,套接字是一个API对象,它们的生命周期不会长过程序的生命周期。但仔细打量一下套接字,它会占用一项特定的资源——缓存,这时ZMQ的开发者可能会问:是否有办法在程序崩溃时让这些套接字缓存得以保留,稍后能够恢复?
这种特性应该会非常有用,虽然不能应对所有的危险,但至少可以挽回一部分损失,特别是多发布-订阅模式来说。让我们来讨论一下。
这里有两个套接字正在欢快地传送着气象信息:
如果接收方(SUB、PULL、REQ)指定了套接字标识,当它们断开网络时,发送方(PUB、PUSH、REP)会为它们缓存信息,直至达到阈值(HWM)。这里发送方不需要有套接字标识。
需要注意,ZMQ的套接字缓存对程序员来说是不可见的,正如TCP缓存一样。
到目前为止,我们使用的套接字都是瞬时套接字。要将瞬时套接字转化为持久套接字,需要为其设定一个套接字标识。所有的ZMQ套接字都会有一个标识,不过是由ZMQ自动生成的UUID。
在ZMQ内部,两个套接字相连时会先交换各自的标识。如果发生对方没有ID,则会自行生成一个用以标识对方:
但套接字也可以告知对方自己的标识,那当它们第二次连接时,就能知道对方的身份:
+-----------+
| |
| Sender |
| |
+-----------+
| Socket |
\-----------/
^ "Lucy! Nice to see you again..."
|
|
| "My name's Lucy"
/-----+-----\
| Socket |
+-----------+
| |
| Receiver |
| |
+-----------+
Figure # - Durable socket
下面这行代码就可以为套接字设置标识,从而建立了一个持久的套接字:
zmq_setsockopt (socket, ZMQ_IDENTITY, "Lucy", 4);
关于套接字标识还有几点说明:
- 如果要为套接字设置标识,必须在连接或绑定至端点之前设置;
- 接收方会选择使用套接字标识,正如cookie在HTTP网页应用中的性质,是由服务器去选择要使用哪个cookie的;
- 套接字标识是二进制字符串;以字节0开头的套接字标识为ZMQ保留标识;
- 不用为多个套接字指定相同的标识,若套接字使用的标识已被占用,它将无法连接至其他套接字;
- 不要使用随机的套接字标识,这样会生成很多持久化套接字,最终让节点崩溃;
- 如果你想获取对方套接字的标识,只有ROUTER套接字会帮你自动完成这件事,使用其他套接字类型时,需要将标识作为消息的一帧发送过来;
- 说了以上这些,使用持久化套接字其实并不明智,因为它会让发送者越来越混乱,让架构变得脆弱。如果我们能重新设计ZMQ,很可能会去掉这种显式声明套接字标识的功能。
其他信息可以查看zmq_setsockopt()函数的ZMQ_IDENTITY一节。注意,该方法只能获取程序中套接字的标识,而不能获得对方套接字的标识。