Элегантное решение для IP C in python с многопроцессорной обработкой - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть два независимых процесса на одной машине, которым требуется IP C. На данный момент у меня есть это рабочее решение:

server.py

#!/usr/bin/python3
from multiprocessing.managers import BaseManager
from multiprocessing import Process, Queue

def do_whatever():
    print('function do whatever, triggered by xyz')
    # do something

def start_queue_server(q):
    class QueueManager(BaseManager): pass

    QueueManager.register('get_queue', callable=lambda:q)
    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    s = m.get_server()
    s.serve_forever()

def main():
    queue = Queue()
    proc = Process(target=start_queue_server, args=(queue,))  
    proc.start()

    while True:
        command = queue.get()
        print('command from queue:', command)

        if command == 'xyz':
            do_whatever()

        # many more if, elif, else statements

if __name__ == "__main__":
    main()

client.py

#!/usr/bin/python3

from multiprocessing.managers import BaseManager

def communicator(command):
    class QueueManager(BaseManager): pass
    QueueManager.register('get_queue')

    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    m.connect()
    queue = m.get_queue()
    queue.put(command)

def main():
    command = ('xyz')
    communicator(command)

if __name__ == "__main__":
    main()
  • Есть ли более элегантный способ вызвать 'do_whwhat', чем анализировать команды, переданные в очередь, а затем вызывать целевую функцию?
  • Можно ли как-то передать ссылку на do_whwhat и вызвать ее непосредственно из клиента?
  • Как ответ от сервера, например, True или False, передается клиенту? Я попытался передать общую переменную вместо объекта очереди, но не получилось. Нужно ли открывать другое соединение, используя второй сокет для передачи ответа?

Я прочитал документацию python, но не смог найти больше вариантов для несвязанных процессов. Входы будут приветствоваться! Приветствия Singultus

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Наконец, я согласился на дополнительный прослушиватель

server.py

#!/usr/bin/python3
from multiprocessing.managers import BaseManager
from multiprocessing import Process, Queue
from multiprocessing.connection import Client

def do_whatever():
    print('function do whatever, triggered by xyz')
    # do something

def start_queue_server(q):
    class QueueManager(BaseManager): pass

    QueueManager.register('get_queue', callable=lambda:q)
    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    s = m.get_server()
    s.serve_forever()

def talkback(msg, port):
    conn = Client(address=('', port), authkey=b'tuktuktuk')
    conn.send(msg)
    conn.close()

def main():
    queue = Queue()
    proc = Process(target=start_queue_server, args=(queue,))  
    proc.start()

    while True:
        command = queue.get()
        print('command from queue:', command)

        if command[0] == 'xyz':
            do_whatever()
            talkback('aaa', command[1])

        # many more if, elif, else statements

if __name__ == "__main__":
    main()

client.py

#!/usr/bin/python3

from multiprocessing.managers import BaseManager
from multiprocessing.connection import Listener

def communicator(command, talkback=False):
    if talkback:
        listener = Listener(address=('', 0), authkey=b'prusaprinter')
        return_port = listener.address[1]
        command = command + (return_port,)

    class QueueManager(BaseManager): pass
    QueueManager.register('get_queue')

    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    m.connect()
    queue = m.get_queue()
    queue.put(command)

    if talkback:
        conn = listener.accept()
        server_return = conn.recv()
        conn.close()
        listener.close()
        return server_return

def main():
    command = ('xyz')
    communicator(command, True)

if __name__ == "__main__":
    main()

Клиент открывает доступный порт и начинает прослушивание в теме. Затем он отправляет команду на сервер вместе с вышеупомянутым номером порта. Сервер выполняет команду, а затем использует номер порта, чтобы сообщить клиенту. После получения ответа клиент закрывает порт.

0 голосов
/ 11 апреля 2020

«Использование REST API» является рекомендуемым и наиболее популярным подходом для взаимодействия клиент-сервер.

REST обеспечивает простой и стандартный формат JSON для обмена данными.

Также позволяет интегрировать с механизмами аутентификации и авторизации.

Он также отлично масштабируется.

Это также позволяет легко обмениваться данными между программами, написанными на разных языках.

Служба RESTful обрабатывает каждый запрос как отдельный поток и, следовательно, по сути обрабатывает многопоточность.

Дополнительная информация: https://realpython.com/api-integration-in-python/

...