Python3 Paho-MQTT速度与Node.js MQTT

时间:2018-11-13 20:52:07

标签: node.js mqtt python-3.7 throughput

我已经使用QoS级别0对Python3和Node.js中的MQTT进行了一些速度测试,发现Node.js比Python3实现要快得多。 怎么会这样? 我愿意使用任一框架作为服务器端的桥梁来处理来自多个客户端的数据。但是,我对应该在服务器上的任何内容上都使用Python3失去了信心。

运行代码段。

Python3:

import paho.mqtt.client as mqtt
import logging
import time
import threading

import json
import sys



class MqttAdaptor(threading.Thread):

    def __init__(self,topic, type=None):
        threading.Thread.__init__(self)
        self.topic = topic

        self.client = None
        self.type = type




    def run(self):


        self.client = mqtt.Client(self.type)


        self.client.on_connect = self.on_connect
        self.client.on_disconnect = self.on_disconnect
        if self.type is not None:
            self.client.connect("localhost", 1883, 60)
            self.client.on_message = self.on_message
            self.client.loop_forever()  
        else:
            self.client.connect_async("localhost", 1883, 60)
            self.client.loop_start()


    # The callback for when the client receives a CONNACK response from the server.
    def on_connect(self,client, userdata, flags, rc):
        self.client.subscribe(self.topic)



    def on_disconnect(self, client, userdata, rc):
        if rc != 0:
            print("Unexpected disconnection from local MQTT broker")


    # The callback for when a PUBLISH message is received from the server.
    def on_message(self,client, userdata, msg):
        jsonMsg = ""
        try:    
            jsonMsg = json.loads(msg.payload)

            if jsonMsg['rssi'] is not None:
                jsonMsg['rssi'] = round(jsonMsg['rssi']*3.3 * 100000)/ 10000

        except:
            pass


        print(json.dumps(jsonMsg))




    def publish(self,topic, payload, qos=0,retain=False):

        self.client.publish(topic,payload,qos,retain)


    def close(self):
        if self.client is not None:
            self.client.loop_stop()
            self.client.disconnect()

if __name__=="__main__":

    topic = '/test/+/input/+'


    subber = MqttAdaptor(topic,'sub')
    subber.start()
    topic = None
    test = MqttAdaptor(topic)
    test.run()

    print("start")
    while True:
        data = sys.stdin.readline()
        if not len(data):
            print("BREAK")
            break
        msg = data.split('\t')
        topic = msg[0]
        test.publish(topic,msg[1],0)
    print("done")
    sys.exit(0)

Node.js:

"use strict";
const fs = require('fs');
const readline = require('readline');
const mqtt = require('mqtt');

const mqttClient = mqtt.connect();

mqttClient.on('connect', () => {
    console.error('==== MQTT connected ====');
    mqttClient.subscribe('/test/+/input/+');
});

mqttClient.on('close', () => {
    console.error('==== MQTT closed ====');
});

mqttClient.on('error', (error) => {
    console.error('==== MQTT error ' + error + ' ====');
});

mqttClient.on('offline', () => {
    console.error('==== MQTT offline ====');
});

mqttClient.on('reconnect', () => {
    console.error('==== MQTT reconnect ====');
});

mqttClient.on('message', (topic, message) => {
    const topicSegments = topic.split('/');
    topicSegments[topicSegments.length - 2] = 'done';
    topic = topicSegments.join('/');

    try {
        //The message might not always be valid JSON
        const json = JSON.parse(message);
        //If rssi is null/undefined in input, it should be left untouched
        if (json.rssi !== undefined && json.rssi !== null) {
            //Multiply by 3 and limit the number of digits after comma     to four
            json.rssi = Math.round(json.rssi * 3.3 * 10000) / 10000;
        }
        console.log(topic + "\t" + JSON.stringify(json));
    } catch (ex) {
        console.error('Error: ' + ex.message);
    }
});


const rl = readline.createInterface({
    input: process.stdin,
    terminal: false,
});

rl.on('line', (line) => {
    const lineSegments = line.split("\t");
    if (lineSegments.length >= 2) {
        const topic = lineSegments[0];
        const message = lineSegments[1];
        mqttClient.publish(topic, message);
    }
});

rl.on('error', () => {
    console.error('==== STDIN error ====');
    process.exit(0);
});

rl.on('pause', () => {
    console.error('==== STDIN paused ====');
    process.exit(0);
});

rl.on('close', () => {
    console.error('==== STDIN closed ====');
    process.exit(0);
});

这两个脚本都在连接到同一代理的命令行上运行。 它们使用脚本管道(节点)运行:

time cat test-performance.txt | pv -l -L 20k -q | nodejs index.js | pv -l | wc -l

和(python):

time cat test-performance.txt | pv -l -L 20k -q | python3 mqttTestThread.py | pv -l | wc -l

测试文件包含以下格式的大约2Gb文本:

/test/meny/input/test   {"sensor":"A1","data1":"176","time":1534512473545}

如脚本所示,我计算了它们运行期间的行数。对于小型测试,Python3脚本的吞吐量约为3k / sec,而node的吞吐量约为20k / sec。 这是一个很大的差异。有谁知道为什么?和/或如何使python以可比的吞吐量运行?

0 个答案:

没有答案