zoukankan      html  css  js  c++  java
  • saltstack系列(二)——zmq应答模式

    python zeromq介绍

      1、ZeroMQ并不是一个对socket的封装,不能用它去实现已有的网络协议。

      2、有自己的模式,不同于更底层的点对点通讯模式。

      3、有比tcp协议更高一级的协议(当然ZeroMQ不一定基于TCP协议,它也可以用于进程间和进程内通讯)。

      4、改变了通讯都基于一对一的连接这个假设。

    zeromq通讯模型

      1、请求应答模型

      由请求端发起请求,并等待回应端回应请求。从请求端来看,一定是一对对收发配对的;反之,在回应端一定是发收对。请求端和回应端都可以是1:N的模型。通常把1认为是server,N认为是Client。0MQ可以很好的支持路由功能(实现路由功能的组件叫做Device),把1:N扩展为N:M(只需要加入若干路由节点)。从这个模型看,更底层的端点地址是对上层隐藏的。每个请求都隐含回应地址,而应用则不关心它。

      2、发布订阅模型

      这个模型里,发布端是单向只发送数据的,且不关心是否把全部的信息都发送给订阅者。如果发布端开始发布信息的时候,订阅端尚未连接上,这些信息直接丢弃。不过一旦订阅连接上来,中间会保证没有信息丢失。同样,订阅端则只负责接收,而不能反馈。如果发布端和订阅端需要交互(比如要确认订阅者是否已经连接上),则使用额外的socket采用请求回应模型满足这个需求。

      3、管道模型

      这个模型里,管道是单向的,从PUSH端单向的向PULL端单向的推送数据流。

    zeromq请求应答模型

      应答模式,就是一问一答,规则有这么几条:

       1、 必须先提问,后回答

            2、 对于一个提问,只能回答一次

            3、 在没有收到回答前不能再次提问

    上代码,服务端: 

    #coding=utf-8  
    
    import zmq  
    import time  
      
    context = zmq.Context()  
    socket = context.socket(zmq.REP)  
    socket.bind('tcp://127.0.0.1:8000')  
      
    while True:  
        message = socket.recv()  
        print 'received request: ' ,message  
          
        time.sleep(1)  
        socket.send('World')  
    

     客户端:

    #coding=utf-8  
    ''''' 
    你无法连续向服务器发送数据,必须发送一次,接收一次 
    REQ和REP模式中,客户端必须先发起请求 
    
    '''  
    import zmq  
      
    context = zmq.Context()  
    print 'connect to hello world server'  
    socket =  context.socket(zmq.REQ)  
    socket.connect('tcp://127.0.0.1:8000')  
      
    for request in range(1,10):  
        print 'send ',request,'...'  
        socket.send('hello')  
        message = socket.recv()  
        print 'received reply ',request,'[',message,']'  
    

    说明:

      客户端总是必须先提问,客户端提问后,必须等待回答,在收到回答前如果又发出提问,那么会报错。  

      zmq.REP是应答方,zmq.REQ是提问方,显然,我们可以有多个提问方,但只能有一个提问方。

    问答环节

    问题1:应答方和提问方谁先启动呢?(服务端和客户端谁先启动呢?)

       答:谁先启动都可以,和pub/sub模式一样

    问题2:如果服务端断掉或者客户端断掉会产生怎样的影响?

      答:如果是客户端断掉,对服务端没有任何影响,如果客户端随后又重新启动,那么两方继续一问一答,但是如果是服务端断掉了,就可能会产生一些问题,这要看服务端是在什么情况下断掉的,如果服务端是在回答完问题后断掉的,那么没影响,重启服务端后,双发继续一问一答,但如果服务端是在收到问题后断掉了,还没来得及回答问题,这就有问题了,那个提问的客户端迟迟得不到答案,就会一直等待答案,因此不会再发送新的提问,服务端重启后,客户端迟迟不发问题,所以也就一直等待提问。

    问题3: 看代码,服务端根本就没去区分提问者是谁,如果有两个提问题的人,如何保证服务端的答案准确的发给那个提问的客户端呢?

      答:关于这一点,大家不必担心,zmq的内部机制已经做了保证,提问者必然只收到属于自己的答案,我们不必去操心zmq是怎么做到的,你只需关于业务本身即可。

    现在,我们把服务端代码做修改

    #coding=utf-8  
    
    import zmq  
    import time  
      
    context = zmq.Context()  
    socket = context.socket(zmq.REP)  
    socket.bind('tcp://127.0.0.1:8000')  
      
    while True:  
        message = socket.recv()  
        print 'received request: ' ,message  
        time.sleep(1)  
        if message == 'hello':  
            socket.send('World')  
        else:  
            socket.send('success')  
    服务端
    #coding=utf-8  
    
    import zmq  
      
    context = zmq.Context()  
    print 'connect to hello world server'  
    socket =  context.socket(zmq.REQ)  
    socket.connect('tcp://127.0.0.1:8000')  
      
    for request in range(1,10):  
        print 'send ',request,'...'  
        socket.send('hello')  
        message = socket.recv()  
        print 'received reply ',request,'[',message,']'  
    客户端1
    #coding=utf-8  
    
    import zmq  
      
    context = zmq.Context()  
    print 'connect to hello world server'  
    socket =  context.socket(zmq.REQ)  
    socket.connect('tcp://127.0.0.1:8000')  
      
    for request in range(1,10):  
        print 'send ',request,'...'  
        socket.send('ok')  
        message = socket.recv()  
        print 'received reply ',request,'[',message,']'  
    客户端2

    实际的运行结果如图:

    不难看出,每个客户端都收到了只属于自己的答案 

  • 相关阅读:
    APP测试
    Pycharm+Rf框架的自动化
    Robot Framework框架做UI自动化测试的介绍
    python-元组
    python-list一些用法
    [Python]之列表list
    接口测试用例(安全测试)
    cookie与session机制
    接口测试与网络通讯原理
    简单常用的SQL命令
  • 原文地址:https://www.cnblogs.com/yezl/p/6604255.html
Copyright © 2011-2022 走看看