def test_exception_compat_v1():
    endpoint = random_ipc_endpoint()

    class MySrv(zerorpc.Server):
        pass

    srv = MySrv()
    srv.bind(endpoint)
    gevent.spawn(srv.run)

    client_events = zerorpc.Events(zmq.XREQ)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    rpccall = client.channel()
    rpccall.emit('donotexist', tuple())
    event = rpccall.recv()
    print event
    assert event.name == 'ERR'
    (name, msg, tb) = event.args
    print 'detailed error', name, msg, tb
    assert name == 'NameError'
    assert msg == 'donotexist'

    rpccall = client.channel()
    rpccall.emit('donotexist', tuple(), xheader=dict(v=1))
    event = rpccall.recv()
    print event
    assert event.name == 'ERR'
    (msg, ) = event.args
    print 'msg only', msg
    assert msg == "NameError('donotexist',)"

    client_events.close()
    srv.close()
示例#2
0
def test_server_manual():
    endpoint = random_ipc_endpoint()

    class MySrv(zerorpc.Server):
        def lolita(self):
            return 42

        def add(self, a, b):
            return a + b

    srv = MySrv()
    srv.bind(endpoint)
    gevent.spawn(srv.run)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    client_channel = client.channel()
    client_channel.emit('lolita', tuple())
    event = client_channel.recv()
    assert event.args == (42, )
    client_channel.close()

    client_channel = client.channel()
    client_channel.emit('add', (1, 2))
    event = client_channel.recv()
    assert event.args == (3, )
    client_channel.close()
    srv.stop()
def test_do_some_req_rep_lost_client():
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=TIME_FACTOR * 2)
        client_bufchan = zerorpc.BufferedChannel(client_hbchan)

        for x in range(10):
            client_bufchan.emit('add', (x, x * x))
            event = client_bufchan.recv()
            assert event.name == 'OK'
            assert list(event.args) == [x + x * x]
        client_bufchan.close()

    coro_pool = gevent.pool.Pool()
    coro_pool.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=TIME_FACTOR * 2)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan)

        for x in range(10):
            event = server_bufchan.recv()
            assert event.name == 'add'
            server_bufchan.emit('OK', (sum(event.args),))

        if sys.version_info < (2, 7):
            assert_raises(zerorpc.LostRemote, server_bufchan.recv)
        else:
            with assert_raises(zerorpc.LostRemote):
                server_bufchan.recv()
        server_bufchan.close()

    coro_pool.spawn(server_do)

    coro_pool.join()
    client.close()
    server.close()
def test_do_some_req_rep_lost_server():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        print 'running'
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel,
                                                   freq=TIME_FACTOR * 2)
        for x in xrange(10):
            client_hbchan.emit('add', (x, x * x))
            event = client_hbchan.recv()
            assert event.name == 'OK'
            assert list(event.args) == [x + x * x]
        client_hbchan.emit('add', (x, x * x))
        if sys.version_info < (2, 7):
            assert_raises(zerorpc.LostRemote, client_hbchan.recv)
        else:
            with assert_raises(zerorpc.LostRemote):
                client_hbchan.recv()
        client_hbchan.close()

    client_task = gevent.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel,
                                                   freq=TIME_FACTOR * 2)
        for x in xrange(10):
            event = server_hbchan.recv()
            assert event.name == 'add'
            server_hbchan.emit('OK', (sum(event.args), ))
        server_hbchan.close()

    server_task = gevent.spawn(server_do)

    server_task.get()
    client_task.get()
    client.close()
    server.close()
示例#5
0
 def create_sub_multiplexer(events,
                            from_event=None,
                            ignore_broadcast=False):
     channel = events.channel(from_event)
     sub_events = zerorpc.WrappedEvents(channel)
     sub_multiplexer = zerorpc.ChannelMultiplexer(
         sub_events, ignore_broadcast=ignore_broadcast)
     return sub_multiplexer
def test_do_some_req_rep_client_timeout():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.XREP)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.XREQ)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=1)
        client_bufchan = zerorpc.BufferedChannel(client_hbchan)

        with assert_raises(zerorpc.TimeoutExpired):
            for x in xrange(10):
                client_bufchan.emit('sleep', (x, ))
                event = client_bufchan.recv(timeout=3)
                assert event.name == 'OK'
                assert event.args == (x, )
        client_bufchan.close()

    client_task = gevent.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=1)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan)

        with assert_raises(zerorpc.LostRemote):
            for x in xrange(20):
                event = server_bufchan.recv()
                assert event.name == 'sleep'
                gevent.sleep(event.args[0])
                server_bufchan.emit('OK', event.args)
        server_bufchan.close()

    server_task = gevent.spawn(server_do)

    server_task.get()
    client_task.get()
    client.close()
    server.close()
def test_do_some_req_rep_lost_server():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.XREP)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.XREQ)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        print 'running'
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=1)
        client_bufchan = zerorpc.BufferedChannel(client_hbchan)
        for x in xrange(10):
            client_bufchan.emit('add', (x, x * x))
            event = client_bufchan.recv()
            assert event.name == 'OK'
            assert event.args == (x + x * x, )
        client_bufchan.emit('add', (x, x * x))
        with assert_raises(zerorpc.LostRemote):
            event = client_bufchan.recv()
        client_bufchan.close()

    client_task = gevent.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=1)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan)
        for x in xrange(10):
            event = server_bufchan.recv()
            assert event.name == 'add'
            server_bufchan.emit('OK', (sum(event.args), ))
        server_bufchan.close()

    server_task = gevent.spawn(server_do)

    server_task.get()
    client_task.get()
    client.close()
    server.close()
def test_do_some_req_rep():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel,
                                                   freq=TIME_FACTOR * 2)
        client_bufchan = zerorpc.BufferedChannel(client_hbchan)
        for x in xrange(20):
            client_bufchan.emit('add', (x, x * x))
            event = client_bufchan.recv()
            assert event.name == 'OK'
            assert list(event.args) == [x + x * x]
        client_bufchan.close()

    coro_pool = gevent.pool.Pool()
    coro_pool.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel,
                                                   freq=TIME_FACTOR * 2)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan)

        for x in xrange(20):
            event = server_bufchan.recv()
            assert event.name == 'add'
            server_bufchan.emit('OK', (sum(event.args), ))
        server_bufchan.close()

    coro_pool.spawn(server_do)

    coro_pool.join()
    client.close()
    server.close()
示例#9
0
def test_events_channel_both_side():
    """
        两边都使用 Channel
    """
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events)

    # client --> server
    client_channel = client.channel()
    client_channel.emit('openthat', (42, ))

    event = server.recv()
    print event
    assert list(event.args) == [42]
    assert event.name == 'openthat'

    # server --> client
    # 如何获取Channel? 根据Event获取Channel
    server_channel = server.channel(event)
    server_channel.emit('test', (21, ))

    event = client_channel.recv()
    assert list(event.args) == [21]
    assert event.name == 'test'

    # server --> client
    server_channel.emit('test', (22, ))

    event = client_channel.recv()
    assert list(event.args) == [22]
    assert event.name == 'test'

    server_events.close()
    server_channel.close()
    client_channel.close()
    client_events.close()
示例#10
0
def test_do_some_req_rep():
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    client_channel = client.channel()
    client_hbchan = zerorpc.HeartBeatOnChannel(client_channel,
                                               freq=TIME_FACTOR * 4)

    event = server.recv()
    server_channel = server.channel(event)
    server_hbchan = zerorpc.HeartBeatOnChannel(server_channel,
                                               freq=TIME_FACTOR * 4)

    def client_do():
        for x in range(20):
            client_hbchan.emit('add', (x, x * x))
            event = client_hbchan.recv()
            assert event.name == 'OK'
            assert list(event.args) == [x + x * x]
        client_hbchan.close()

    client_task = gevent.spawn(client_do)

    def server_do():
        for x in range(20):
            event = server_hbchan.recv()
            assert event.name == 'add'
            server_hbchan.emit('OK', (sum(event.args), ))
        server_hbchan.close()

    server_task = gevent.spawn(server_do)

    server_task.get()
    client_task.get()
    client.close()
    server.close()
示例#11
0
def test_heartbeat_can_open_channel_client_close():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    client_channel = client.channel()
    client_hbchan = zerorpc.HeartBeatOnChannel(client_channel,
                                               freq=TIME_FACTOR * 2)
    client_bufchan = zerorpc.BufferedChannel(client_hbchan)

    def server_fn():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel,
                                                   freq=TIME_FACTOR * 2)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan)
        try:
            while True:
                gevent.sleep(1)
        finally:
            server_bufchan.close()

    server_coro = gevent.spawn(server_fn)

    gevent.sleep(TIME_FACTOR * 3)
    print('CLOSE CLIENT SOCKET!!!')
    client_bufchan.close()
    client.close()
    if sys.version_info < (2, 7):
        assert_raises(zerorpc.LostRemote, server_coro.get)
    else:
        with assert_raises(zerorpc.LostRemote):
            server_coro.get()
    print('SERVER LOST CLIENT :)')
    server.close()
示例#12
0
def test_events_channel_client_side():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.XREP)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.XREQ)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events)

    client_channel = client.channel()
    client_channel.emit('someevent', (42,))

    event = server.recv()
    print event
    assert event.args == (42,)
    assert event.header.get('zmqid', None) is not None

    server.emit('someanswer', (21,),
            xheader=dict(response_to=event.header['message_id'],
                zmqid=event.header['zmqid']))
    event = client_channel.recv()
    assert event.args == (21,)
示例#13
0
def test_close_server_hbchan():
    endpoint = random_ipc_endpoint()

    # 创建Server
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    # 创建Client
    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    client_channel = client.channel()
    client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=2)
    client_hbchan.emit('openthat', None)

    event = server.recv()
    server_channel = server.channel(event)
    server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=2)
    server_hbchan.recv()

    gevent.sleep(3)
    print 'CLOSE SERVER SOCKET!!!'
    server_hbchan.close()

    # 服务器关闭服务
    if sys.version_info < (2, 7):
        assert_raises(zerorpc.LostRemote, client_hbchan.recv)
    else:
        with assert_raises(zerorpc.LostRemote):
            client_hbchan.recv()
    print 'CLIENT LOST SERVER :)'
    client_hbchan.close()
    server.close()
    client.close()
示例#14
0
def test_events_channel_client_side():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events)

    client_channel = client.channel()
    client_channel.emit('someevent', (42,))

    event = server.recv()
    print(event)
    assert list(event.args) == [42]
    assert event.identity is not None

    reply_event = server.new_event('someanswer', (21,),
            xheader=dict(response_to=event.header['message_id']))
    reply_event.identity = event.identity
    server.emit_event(reply_event)
    event = client_channel.recv()
    assert list(event.args) == [21]
示例#15
0
def test_recursive_multiplexer():
    endpoint = random_ipc_endpoint()

    server_events = zerorpc.Events(zmq.XREP)
    server_events.bind(endpoint)
    servermux = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.XREQ)
    client_events.connect(endpoint)
    clientmux = zerorpc.ChannelMultiplexer(client_events,
                                           ignore_broadcast=True)

    def ping_pong(climux, srvmux):
        cli_chan = climux.channel()
        someid = random.randint(0, 1000000)
        print 'ping...'
        cli_chan.emit('ping', someid)
        print 'srv_chan got:'
        event = srvmux.recv()
        srv_chan = srvmux.channel(event)
        print event
        assert event.name == 'ping'
        assert event.args == someid
        print 'pong...'
        srv_chan.emit('pong', someid)
        print 'cli_chan got:'
        event = cli_chan.recv()
        print event
        assert event.name == 'pong'
        assert event.args == someid
        srv_chan.close()
        cli_chan.close()

    def create_sub_multiplexer(events,
                               from_event=None,
                               ignore_broadcast=False):
        channel = events.channel(from_event)
        sub_events = zerorpc.WrappedEvents(channel)
        sub_multiplexer = zerorpc.ChannelMultiplexer(
            sub_events, ignore_broadcast=ignore_broadcast)
        return sub_multiplexer

    def open_sub_multiplexer(climux, srvmux):
        someid = random.randint(0, 1000000)
        print 'open...'
        clisubmux = create_sub_multiplexer(climux, ignore_broadcast=True)
        clisubmux.emit('open that', someid)
        print 'srvsubmux got:'
        event = srvmux.recv()
        assert event.name == 'w'
        srvsubmux = create_sub_multiplexer(srvmux, event)
        event = srvsubmux.recv()
        print event
        return (clisubmux, srvsubmux)

    ping_pong(clientmux, servermux)

    (clientmux_lv2, servermux_lv2) = open_sub_multiplexer(clientmux, servermux)
    ping_pong(clientmux_lv2, servermux_lv2)

    (clientmux_lv3,
     servermux_lv3) = open_sub_multiplexer(clientmux_lv2, servermux_lv2)
    ping_pong(clientmux_lv3, servermux_lv3)

    (clientmux_lv4,
     servermux_lv4) = open_sub_multiplexer(clientmux_lv3, servermux_lv3)
    ping_pong(clientmux_lv4, servermux_lv4)

    ping_pong(clientmux_lv4, servermux_lv4)
    ping_pong(clientmux_lv3, servermux_lv3)
    ping_pong(clientmux_lv2, servermux_lv2)
    ping_pong(clientmux, servermux)
    ping_pong(clientmux, servermux)
    ping_pong(clientmux_lv2, servermux_lv2)
    ping_pong(clientmux_lv4, servermux_lv4)
    ping_pong(clientmux_lv3, servermux_lv3)

    (clientmux_lv5,
     servermux_lv5) = open_sub_multiplexer(clientmux_lv4, servermux_lv4)
    ping_pong(clientmux_lv5, servermux_lv5)
def test_do_some_req_rep_client_timeout():
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=TIME_FACTOR * 2)
        client_bufchan = zerorpc.BufferedChannel(client_hbchan)

        if sys.version_info < (2, 7):
            def _do_with_assert_raises():
                for x in range(10):
                    client_bufchan.emit('sleep', (x,))
                    event = client_bufchan.recv(timeout=TIME_FACTOR * 3)
                    assert event.name == 'OK'
                    assert list(event.args) == [x]
            assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises)
        else:
            with assert_raises(zerorpc.TimeoutExpired):
                for x in range(10):
                    client_bufchan.emit('sleep', (x,))
                    event = client_bufchan.recv(timeout=TIME_FACTOR * 3)
                    assert event.name == 'OK'
                    assert list(event.args) == [x]
        client_bufchan.close()

    coro_pool = gevent.pool.Pool()
    coro_pool.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=TIME_FACTOR * 2)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan)

        if sys.version_info < (2, 7):
            def _do_with_assert_raises():
                for x in range(20):
                    event = server_bufchan.recv()
                    assert event.name == 'sleep'
                    gevent.sleep(TIME_FACTOR * event.args[0])
                    server_bufchan.emit('OK', event.args)
            assert_raises(zerorpc.LostRemote, _do_with_assert_raises)
        else:
            with assert_raises(zerorpc.LostRemote):
                for x in range(20):
                    event = server_bufchan.recv()
                    assert event.name == 'sleep'
                    gevent.sleep(TIME_FACTOR * event.args[0])
                    server_bufchan.emit('OK', event.args)
        server_bufchan.close()


    coro_pool.spawn(server_do)

    coro_pool.join()
    client.close()
    server.close()
def test_congestion_control_server_pushing():
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    read_cnt = type('Dummy', (object,), { "value": 0 })

    def client_do():
        client_channel = client.channel()
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=TIME_FACTOR * 2)
        client_bufchan = zerorpc.BufferedChannel(client_hbchan, inqueue_size=100)
        for x in range(200):
            event = client_bufchan.recv()
            assert event.name == 'coucou'
            assert event.args == x
            read_cnt.value += 1
        client_bufchan.close()

    coro_pool = gevent.pool.Pool()
    coro_pool.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=TIME_FACTOR * 2)
        server_bufchan = zerorpc.BufferedChannel(server_hbchan, inqueue_size=100)
        if sys.version_info < (2, 7):
            def _do_with_assert_raises():
                for x in range(200):
                    server_bufchan.emit('coucou', x, timeout=0)  # will fail when x == 1
            assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises)
        else:
            with assert_raises(zerorpc.TimeoutExpired):
                for x in range(200):
                    server_bufchan.emit('coucou', x, timeout=0)  # will fail when x == 1
        server_bufchan.emit('coucou', 1)  # block until receiver is ready
        if sys.version_info < (2, 7):
            def _do_with_assert_raises():
                for x in range(2, 200):
                    server_bufchan.emit('coucou', x, timeout=0)  # will fail when x == 100
            assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises)
        else:
            with assert_raises(zerorpc.TimeoutExpired):
                for x in range(2, 200):
                    server_bufchan.emit('coucou', x, timeout=0)  # will fail when x == 100
        for x in range(read_cnt.value, 200):
            server_bufchan.emit('coucou', x) # block until receiver is ready
        server_bufchan.close()

    coro_pool.spawn(server_do)
    try:
        coro_pool.join()
    except zerorpc.LostRemote:
        pass
    finally:
        client.close()
        server.close()
示例#18
0
def test_do_some_req_rep_client_timeout():
    endpoint = random_ipc_endpoint()
    server_events = zerorpc.Events(zmq.ROUTER)
    server_events.bind(endpoint)
    server = zerorpc.ChannelMultiplexer(server_events)

    client_events = zerorpc.Events(zmq.DEALER)
    client_events.connect(endpoint)
    client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)

    def client_do():
        # client创建一个chanel, 并在上面创建 HeartBeatOnChannel
        # response_to
        # Each consecutive event on a channel will have the header field "response_to" set to the channel id:
        # 第一个Event的Id, 之后所有的Event, 无论是在服务器还是在Client, 都共享相同的数据
        #
        client_channel = client.channel()

        # 主动心跳?
        client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=2)

        if sys.version_info < (2, 7):

            def _do_with_assert_raises():
                for x in xrange(10):
                    # client发送Event到server, 并且等待服务器的返回
                    client_hbchan.emit('sleep', (x, ))
                    event = client_hbchan.recv(
                        timeout=3
                    )  # x: 0, 1, 2正常返回, x: 3+ 返回异常, TimeoutExpired

                    # 心跳的作用?

                    print event
                    assert event.name == 'OK'
                    assert list(event.args) == [x]

            assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises)
        else:
            with assert_raises(zerorpc.TimeoutExpired):
                for x in xrange(10):
                    client_hbchan.emit('sleep', (x, ))
                    event = client_hbchan.recv(timeout=3)
                    print event
                    assert event.name == 'OK'
                    assert list(event.args) == [x]
        client_hbchan.close()

    client_task = gevent.spawn(client_do)

    def server_do():
        event = server.recv()
        server_channel = server.channel(event)
        server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=2)

        if sys.version_info < (2, 7):

            def _do_with_assert_raises():
                for x in xrange(20):
                    event = server_hbchan.recv()
                    print event

                    assert event.name == 'sleep'
                    gevent.sleep(event.args[0])
                    server_hbchan.emit('OK', event.args)

            assert_raises(zerorpc.LostRemote, _do_with_assert_raises)
        else:
            with assert_raises(zerorpc.LostRemote):
                for x in xrange(20):
                    # 服务器接口大量的Event, 但是中途发现: client 关闭, 心跳结束,然后服务器的请求也就终止
                    event = server_hbchan.recv()
                    print event
                    assert event.name == 'sleep'
                    gevent.sleep(event.args[0])
                    server_hbchan.emit('OK', event.args)
        server_hbchan.close()

    server_task = gevent.spawn(server_do)

    server_task.get()
    client_task.get()
    client.close()
    server.close()