pynng 超快速上手,但不保熟

nng 是 zeromq 的后辈,nanomsg 的 下一代的消息处理库。
主要就是快,上手超快,消息收发也超快。
本机 python 3.9 + pynng 0.7.1 本地环回测试 10000次1G数据,只需要1秒就可以完成。

nng相比zeromq的目前发现优势,链接状态全自动维护,自动重连,掉线重连能快速恢复,数据发送不完整时能自动无限重发(默认情况),报头能全定义从而能支持http协议,速度飞快。

以下4个简单完整例子
_try_push_pull.py
_try_pair_pair.py
_try_pub_sub.py
_try_rep_req.py

pynng安装

pip install -U pynng

_try_push_pull.py

from pynng import nng
from multiprocessing import Process
import numpy as np
import pickle


def proc_send_data():
    '''
    push端只管发数据
    :return:
    '''
    sock = nng.Push0(dial='tcp://127.0.0.1:8855')
    for i in range(10000):
        data = np.random.uniform([128, 4, 512, 512])
        data = pickle.dumps(data)
        sock.send(data)
    sock.close()


def proc_recv_data():
    '''
    pull端只管收数据
    :return:
    '''
    sock = nng.Pull0(listen='tcp://127.0.0.1:8855')
    for i in range(10000):
        r = sock.recv(block=True)
        data = pickle.loads(r)
        print(i, np.mean(data))
    sock.close()


if __name__ == '__main__':
    p1 = Process(target=proc_recv_data, daemon=True)
    p2 = Process(target=proc_send_data, daemon=True)

    print('start')
    p1.start()
    p2.start()

    p1.join()
    p2.join()
    print('success')

_try_pair_pair.py

from pynng import nng
from pynng.exceptions import TryAgain, Timeout
from multiprocessing import Process
import numpy as np
import pickle
import random


def proc_send_data():
    '''
    pair端想发就发,想收就收
    如果发消息前,对端已经关掉了,那么将会卡在send函数那里,直到对端重新打开,或send_timeout超时
    :return:
    '''
    sock = nng.Pair0(dial='tcp://127.0.0.1:8855', recv_timeout=500, send_timeout=500)
    for i in range(10000):
        # 发送1G的数据。128*4*512*512*8/1024/1024=1024MB
        data = np.random.uniform([128, 4, 512, 512])
        data = pickle.dumps(data)

        try:
            sock.send(data)
        except Timeout:
            # 如果对面端提前关了,那么这里会超时,这里直接跳出
            break

        if random.random() < 0.5:
            try:
                r = sock.recv(block=False)
                print(r)
            except TryAgain:
                pass
    print('end1')
    sock.close()


def proc_recv_data():
    '''
    pair端想发就发,想收就收
    :return:
    '''
    sock = nng.Pair0(listen='tcp://127.0.0.1:8855', recv_timeout=500, send_timeout=500)
    for i in range(10000):
        try:
            r = sock.recv(block=False)
            data = pickle.loads(r)
            print(i, np.mean(data))
        except TryAgain:
            # 如果没有消息
            pass

        if random.random() < 0.5:
            try:
                sock.send(bytes([1]))
            except Timeout:
                # 如果对面端提前关了,那么这里会超时,这里直接跳出
                break

    print('end2')
    sock.close()


if __name__ == '__main__':
    p1 = Process(target=proc_recv_data, daemon=True)
    p2 = Process(target=proc_send_data, daemon=True)

    p1.start()
    p2.start()

    p1.join()
    p2.join()
    print('success')

_try_pub_sub.py

from pynng import nng
from multiprocessing import Process
import numpy as np
import pickle
from pynng.exceptions import TryAgain


def proc_send_data():
    '''
    pub端 和push端相似,只管发数据
    :return:
    '''
    sock = nng.Pub0(listen='tcp://127.0.0.1:8855')
    for i in range(10000):
        data = np.random.uniform([128, 4, 512, 512])
        data = pickle.dumps(data)
        sock.send(data)
    sock.close()


def proc_recv_data():
    '''
    sub端 和pull端相似,只管收数据。可以设定订阅标题和取消订阅标题。
    首次使用时,要设定为接收空标题,不然啥也收不到
    :return:
    '''
    sock = nng.Sub0(dial='tcp://127.0.0.1:8855')
    # 设定接受空标题
    sock.subscribe('')
    for i in range(10000):
        try:
            r = sock.recv(block=False)
            data = pickle.loads(r)
            print(i, np.mean(data))
        except TryAgain:
            print()
    sock.close()


if __name__ == '__main__':
    p1 = Process(target=proc_recv_data, daemon=True)
    p2 = Process(target=proc_send_data, daemon=True)

    p1.start()
    p2.start()

    p1.join()
    p2.join()
    print('success')

_try_rep_req.py

from pynng import nng
from multiprocessing import Process
import numpy as np
import pickle


def proc_send_data():
    '''
    req端一开始只能发送数据,并且发送完数据后,必定要接收数据
    :return:
    '''
    sock = nng.Req0(dial='tcp://127.0.0.1:8855')
    for i in range(10000):
        data = np.random.uniform([128, 4, 512, 512])
        data = pickle.dumps(data)
        sock.send(data)
        sock.recv()
    sock.close()


def proc_recv_data():
    '''
    rep端一开始只能接收数据,并且接收完数据后,必定要发送一个长度不为0的数据
    :return:
    '''
    sock = nng.Rep0(listen='tcp://127.0.0.1:8855')
    for i in range(10000):
        r = sock.recv(block=True)
        data = pickle.loads(r)
        print(i, np.mean(data))
        # rep发送的数据长度不能为0
        sock.send(bytes([0]))
    sock.close()


if __name__ == '__main__':
    p1 = Process(target=proc_recv_data, daemon=True)
    p2 = Process(target=proc_send_data, daemon=True)

    p1.start()
    p2.start()

    p1.join()
    p2.join()
    print('success')

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值