Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何与pyzmq一起使用inproc传输?_Python_Sockets_Publish Subscribe_Pyzmq_Inproc - Fatal编程技术网

Python 如何与pyzmq一起使用inproc传输?

Python 如何与pyzmq一起使用inproc传输?,python,sockets,publish-subscribe,pyzmq,inproc,Python,Sockets,Publish Subscribe,Pyzmq,Inproc,我用pyzmq建立了两个小脚本,模拟发布和订阅过程。但是,我无法使用inproc传输将消息发送到我的订户客户端。我能够使用tcp://127.0.0.1:8080很好,只是不在程序中 pub_server.py import zmq import random import sys import time context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("inproc://stream") while

我用pyzmq建立了两个小脚本,模拟发布和订阅过程。但是,我无法使用
inproc
传输将消息发送到我的订户客户端。我能够使用
tcp://127.0.0.1:8080
很好,只是不在程序中

pub_server.py

import zmq
import random
import sys
import time

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("inproc://stream")

while True:
    socket.send_string("Hello")
    time.sleep(1)
import sys
import zmq

# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt_string(zmq.SUBSCRIBE, '')
socket.connect("inproc://stream")

for x in range (5):
    string = socket.recv()
    print(string)
sub_client.py

import zmq
import random
import sys
import time

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("inproc://stream")

while True:
    socket.send_string("Hello")
    time.sleep(1)
import sys
import zmq

# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt_string(zmq.SUBSCRIBE, '')
socket.connect("inproc://stream")

for x in range (5):
    string = socket.recv()
    print(string)
如何成功地修改代码,以便能够在两个脚本之间使用inproc传输方法

编辑:

我已经更新了我的代码,以进一步反映@larsks评论。我仍然没有收到我发布的字符串-我做错了什么

import threading
import zmq

def pub():
    context = zmq.Context()
    sender = context.socket(zmq.PUB)
    sender.connect("inproc://hello")
    lock = threading.RLock()

    with lock:
        sender.send(b"")

def sub():
    context = zmq.Context()
    receiver = context.socket(zmq.SUB)
    receiver.bind("inproc://hello")

    pub()

    # Wait for signal
    string = receiver.recv()
    print(string)
    print("Test successful!")

    receiver.close()

if __name__ == "__main__":
    sub()

顾名思义,
inproc
sockets只能在同一进程中使用。如果要重写客户机和服务器,使同一进程中有两个线程,则可以使用
inproc
,否则,这种套接字类型根本不适合您所做的工作

在这一点上,我们的立场非常明确:

进程内传输通过内存在共享单个ØMQ上下文的线程之间直接传递消息

更新

看看更新后的代码,首先突出的问题是,尽管上面引用的文档中说“……在共享单个ØMQ上下文的线程之间”,但您正在代码中创建两个上下文。通常,在程序中只调用一次
zmq.Context()

其次,您从未向订阅者订阅任何消息,因此即使其他一切正常,您也不会收到任何消息

最后,您的代码将体验:

关于PUB-SUB套接字,还有一件更重要的事情需要知道:您不知道订阅者何时开始接收消息。即使您启动订阅服务器,等待一段时间,然后启动发布服务器,订阅服务器也将始终错过发布服务器发送的第一条消息。这是因为当订阅者连接到发布者时(这需要很短但非零的时间),发布者可能已经在发送消息了

发布/订阅模型并不适用于单个消息,也不适用于可靠的传输

总而言之:

  • 在创建套接字之前,需要创建共享ZMQ上下文
  • 您可能希望您的发布者在循环中发布,而不是发布单个消息。由于您试图使用
    inproc
    sockets,因此需要将两个函数放在不同的线程中
  • 您需要设置订阅筛选器才能接收消息

ZMQ文档中有一个可能提供有用起点的示例
PAIR
sockets设计用于协调
inproc
sockets上的线程,与pub/sub sockets不同,它们是双向的,不受“慢速连接”问题的影响。

谢谢@larsks。然而,我已经编辑了我的问题,并将我修改过的脚本与你的答案结合在一起,但我仍然没有收到我发布的任何东西。我可能做错了什么?我已经做了一个更新,希望能为你指明正确的方向。