使用 ZMQ 从 Python 脚本接收 Electron 中的数组

问题描述 投票:0回答:1

我正在 Electron 中制作一个应用程序,并使用 Python 脚本进行查询(SQL)。 我需要将 SQL 查询的结果发送到 Electron 以在数据表中显示此数据。 我读到最好的通信方式是使用 ZMQ 库。但我不知道这是否是最好的选择。

我正在使用以下代码,如果数组(结果)很小,则该代码有效,但如果它有几行,则不会发送数组。

我正在使用以下代码,如果数组(结果)很小,则该代码有效,但如果它有几行,则不会发送该数组。 我很感激您的帮助。

应用程序.py

import zmq
from json import loads, dumps
import signal
from threading import Thread

#.......
def dataSocket():
    global message
    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://*:7778")

    while True:
        message = loads(socket.recv())
        #....
        if message['type']=='command':
            result = querySQL() # result = [['val1','val2','val3','val4','val5','val6','val7','val8','val9','val10'],[...],[...],...,[...]]
            socket.send(dumps(result).encode())
#.......
if __name__ == "__main__":

    signal.signal(signal.SIGINT, signal.SIG_DFL)

    Thread(target = dataSocket).start()

渲染.js

const ZMQ = require('zeromq');
const { stringify } = JSON;

const dataSock = new ZMQ.Request;
dataSock.connect("tcp://127.0.0.1:7778");

$('#sendCommand').on("click", async() => {
    await dataSock.send(stringify({ type: "command", data: "" }));
    [dataResponse] = await dataSock.receive();
    $('#result-data').val(JSON.parse(dataResponse.toString()));
    console.log(JSON.parse(dataResponse.toString()));
})
python electron zeromq
1个回答
0
投票

看起来您正在将 SQL 查询结果作为字符串转储到 ZMQ 消息中,并希望在 Electron 的另一端可以将其解析为 JSON。

我的建议是采用像 Google Protocol Buffers 这样的东西,序列化你想要从 Python 发送的数据,然后在 Electron (JavaScript) 中再次反序列化,并使用 ZeroMQ 来传输其间的序列化数据。这样做的目的是消除有关 Python 和 Electron / JavaScript 将如何处理/解析数据的任何歧义。它还允许您安全地拥有更复杂的数据结构;例如,如果还用于序列化您的命令,您还可以传递参数。

如果您以前没有使用过它们,您可以在 GPB .proto 文件中描述您想要发送的消息。如果您的 SQL 查询要返回二维数组,它可能看起来像这样:

message ResultLine
{
    repeated int Values = 1;
}

message Results
{
    repeated ResultLine Lines = 2;
}

然后使用 GPB 编译器编译该 .proto 文件,该编译器可以生成 Python 和 JavaScript 源代码。该源代码定义了类似于 Results 和 ResultLine 的类,以及将它们序列化和反序列化为 GPB 有线格式所需的所有代码。 Results 类实际上是一个二维整数数组。

因此,在 Python 中,您将为 SQL 返回中的每一行数据实例化一个新的 ResultsLine,并用该行的值填充它。然后,您可以将该 ResultsLine 添加到 Results 对象(您之前已实例化)。当你对每一行都这样做时,你会做类似的事情(这是伪代码,不是 Python)

Result = new Result
foreach row in SQLResponse
    ResultLine = new ResultLine
    foreach val in row
        ResultLine.Values.Add(val)
    Result.Lines.Add(ResultLine)

zmqMsg=new ZMQMsg(Results.SerialiseToString())
socket.send(zmqMsg)

可能有一种非常Pythonic的方式来进行迭代,并且重复值字段可能有直接摄取数组的方法(我对Python中的GPB不太熟悉)。而在另一端,

zmqMsg = socket.recv()
Results = Results.ParseFromString(zmqMsg.Content)

瞧,您现在有了一个包含您想要的数据的 Results 对象。

处理所有这些麻烦的一个非常好的事情是,您并不真正关心 ZMQ 套接字的另一端是什么。它同样可以是 C++、C#、Java、Kotlin、Go; Google Protocol Buffers 和 ZMQ 都得到了广泛的支持。你也有很大的灵活性;如果你想制作要发送的消息,只需更新 .proto 文件并重新编译,几乎所有传达额外消息字段所需的工作都已完成;您只需填充并使用它们即可。

GPB 的有线格式是二进制的,但它也有 JSON 的方言。这也很有用。

© www.soinside.com 2019 - 2024. All rights reserved.