ZMQ通信协议小结

文章目录

    • ZMQ 通信协议小结
      • 前言
      • zmq的三种模型
          • 1、Request_Reply模式(请求——应答): REP、 REQ
            • 伪代码
            • 应用场景
          • 2、Publish-Subscribe模式(发布——订阅): PUB、SUB
            • 伪代码
            • 应用场景
          • 3、Parallel Pipeline模式(push——pull): PUSH、PULL
            • 伪代码
            • 应用场景

ZMQ 通信协议小结

  • 前言

    项目中涉及到 zmq通信协议相关内容,所以将学习、使用过程同步分享,
    Talk is cheap, Show me the cod, 通篇以代码分享为主,且本文对底层socket不做过多叙述,以实际应用为准,希望能帮到各位!

  • zmq的三种模型

    1、Request_Reply模式(请求——应答): REP、 REQ
    	一发一收 无缓存 断开连接数据丢失。
    	 双向消息,REP端负责send消息,必须recv到REQ的返回,否则通道堵塞
    
    伪代码
    # 1、Request_Reply模式
    # server
    import zmq
    
    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind('tcp://*:5556')
    
    while True:
        message = socket.recv()
        print(message)
        socket.send('server response')
    ----------------------------------------------------------
    # client 
    import zmq
    import sys
    
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.connect('tcp://localhost:5556')
    
    while True:
        data = raw_input('input your data:')
        if data == 'q':
            sys.exit()
        socket.send(data)
        response = socket.recv()
        print(response)
    
    
    应用场景

    场景说明: 我们定义一个非阻塞 的消息通道, 用作发送特定的Python结构体数据,包含三个文件如下:

    1.server.py

    import time
    import zmq
    from data import zmqStruct
    
    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://ip:5656")
    
    while True:
        try:
            message = socket.recv_pyobj(zmq.NOBLOCK)
            print(message)
            #time.sleep(1)
            socket.send_pyobj('123123123')
        except zmq.Again as e:
            if e.erron!=zmq.EAGAIN:
                print(repr(e))
    
        time.sleep(1)
    

    2.client.py

    from data import zmqStruct
    
    def zmqREQ():
        import zmq
        context = zmq.Context()
        socket = context.socket(zmq.REQ)
        socket.connect("tcp://{}:5656".format('192.168.24.107'))
        return socket
    
    sendStruct = zmqStruct()
    zmqClient = zmqREQ()
    zmqClient.send_pyobj(sendStruct)
    print zmqClient.recv_pyobj()
    
    

    3.data.py

    class zmqStruct(onject):  # 消息结构体
    	def __init__(self, cmd=0, data=None, desc=''):
            self.cmd = cmd
            self.data = data
            self.desc = desc
    
    2、Publish-Subscribe模式(发布——订阅): PUB、SUB
    	广播所有client,无缓存,断开连接数据丢失。
    	发布端发布主题topic,订阅端只会收到已订阅的主题topic
    
    伪代码
    # 2、Publish-Subscribe模式
    # server
    import zmq
    
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:5005")
    while True:
        msg = input('input your data:').encode('utf-8')
        socket.send(msg)
    ------------------------------------------------------------------
    # client
    import zmq
    
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect('tcp://127.0.0.1:5005')
    # 使用socket.setsockopt()进行过滤
    socket.setsockopt(zmq.SUBSCRIBE,b'')
    while True:
        print(socket.recv_string())
    
    应用场景

    场景说明

    Code

    
    

    Error

    
    
    
    3、Parallel Pipeline模式(push——pull): PUSH、PULL
    	>>可以由三部分组成:push推送数据,work缓存数据,pull竞争数据,断开连接数据不丢失,重连继续发送。work中间件可以去掉
    	>> 单向通道,push的消息,只能有一个pull端进行接收
    
    伪代码
    # 3、Parallel Pipeline模式
    # server
    import zmq
    
    context = zmq.Context()
    socket = context.socket(zmq.PULL)
    socket.bind('tcp://*:5566')
    while True:
        data = socket.recv()
        print(data)
    ---------------------------------------------
    # work   无work  push 会阻塞掉
    import zmq
    
    context = zmq.Context()
    
    recive = context.socket(zmq.PULL)
    recive.connect('tcp://127.0.0.1:5565')
    sender = context.socket(zmq.PUSH)
    sender.connect('tcp://127.0.0.1:5566')
    
    while True:
        data = recive.recv()
        sender.send(data)
    ---------------------------------------------
    # client
    import zmq
    import time
    
    context = zmq.Context()
    socket = context.socket(zmq.PUSH)
    
    socket.bind('tcp://*:5565')
    
    while True:
        data = raw_input('input your data:')
        socket.send(data)
    
    应用场景

    场景说明

    Code

    
    

    Error

    
    
    

你可能感兴趣的:(socket通信)