Поддерживать связь с помощью скрипта Python, запущенного на сервере

#python #node.js #websocket

#python #node.js #websocket

Вопрос:

Это то, что я разработал до сих пор. Во-первых, мой сервер websocket:

 // app.js
const spawn = require('child_process');
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 8080 })

wss.on('connection',ws => {
  ws.on('message', message => {
    const python = spawn('python', ['-u', 'main.py', message])
    python.stdout.on('data', function (data) {
      // Pipe data from python script ...
      dataToSend = data.toString('utf8');
      ws.send(dataToSend)
     });
     python.on('error', err => {
       console.log(err)
     })
  })
  ws.on('close', () => {
    console.log('Client has disconected')
  })
}).on('error', err => {
  console.log(err)
})
  

It basics использует child_process для создания скрипта Python, передающего message , который был отправлен с клиента.
-u передается для очистки отпечатков скрипта Python, чтобы их можно было транслировать на python.stdout и отправлять клиенту.

Это мой скрипт Python, который вызывается из app.js сервер websocket:

 # main.py
import time, sys
i = int(sys.argv[1])
while i > 0:
    print(i)
    i-=1
    time.sleep(1)
    # this while is just anexemple of some pre-script process
    # (for exemple, signin on user account)

# after signin...
print('input something from client: ')
x = input()

while True:
    print(x)
    time.sleep(1)
    # use input x variable
    # here is where my code happens and the program keeps executing
    pass
  

Как вы можете видеть, я использую message переданный spawn() с сервера, чтобы сохранить свой первый while работоспособным. Это просто пример того, что мне понадобится такой ввод от пользователя.

Продолжайте уделять внимание x = input() , потому что это моя главная проблема

И, наконец, мой клиентский websocket

 // client.js
const WebSocket = require('ws');
let socket = new WebSocket("ws://localhost:8080");

socket.onopen = function(e) {
    let someClientInfo = 2
    console.log("sending data...");
    socket.send(someClientInfo);

};

socket.onmessage = function(event) {
    console.log('Output of python script: '   event.data.toString('utf-8'));
};

socket.onerror = function(event) {
    console.log(event);
};
  

Ит-основы передают этот первый аргумент someClientInfo , а затем получают вывод скрипта python следующим образом:

 sending data...

Output of python script: 2 

Output of python script: 1

Output of python script: input something from client:
  

Конечно, когда клиент получает эту последнюю строку, он продолжает зависать, потому что он ничего не может ввести со своей стороны. Он просто получает поток выходных данных из python.

Кто-нибудь знает, возможно ли передать этот второй ввод в мой запущенный скрипт python? Я начинаю думать, что, возможно, это невозможно, но я не могу придумать другой способ сделать это. Если это то, что child_process невозможно сделать, какой способ мне следует искать?

Моя главная цель — поддерживать постоянную связь со скриптом python, запущенным на сервере, чтобы я мог передавать эти входные данные от клиента к python.

Я хочу иметь возможность отключаться от этого сокета, а затем снова подключаться и продолжать получать выходные данные скрипта Python. До сих пор я не мог найти способ сделать это тоже.

Мой основной скрипт не может находиться внутри кода сервера (возможно, если вы рассказали о базовой реализации flask или что-то в этом роде), потому что я хочу иметь возможность запускать несколько скриптов, и каждый клиентский пользователь должен иметь возможность продолжать выполнять итерации со своим собственным скриптом python, запущенным на сервере. У каждого пользователя будет свой main.py

До сих пор я не задумывался о том, как я буду поддерживать весь этот процесс на сервере, или даже о том, безопасно ли делать что-то подобное. Любой совет по этому поводу будет очень оценен, и я тоже буду очень благодарен.

Комментарии:

1. «Я не смогу запускать несколько скриптов» — Я думаю, что вы можете, вы думали о создании main.py из python и передаче «объекта» соединения main.py ? Таким образом, ваш клиент может напрямую отправлять данные на main.py .

2. или — если вам ДЕЙСТВИТЕЛЬНО нужно node.js — вы можете сделать это. сначала появляется main.py с x помощью. Завершите программу, как только это потребуется x , и верните все variables . Возродите другой main.py , но вместо того, чтобы передавать x только, передайте main.py (если вы выполняете повторную задачу). Если ваша задача не является «повторной», создайте необходимый скрипт по порядку. login.py , comment.py

3. «каждый клиентский пользователь должен иметь возможность продолжать выполнять итерации со своим собственным скриптом python, запущенным на сервере » — Каждый клиент будет продолжать взаимодействовать с «не своим» скриптом python в flask. Но вы можете отправить клиенту «cookie». Вы знакомы с cookies? Два предыдущих «возможных» решения не используются в производстве или где-либо подобном…

4. Я не очень хорошо знаком с файлами cookie, могу ли я их использовать? Я не хочу запускать его в Интернете, он должен быть запущен на сервере и продолжать работать, если пользователь отключится. Проблема с этим подходом flask заключается в том, что мне нужны отдельные среды для каждого пользователя (конфигурационные файлы и прочее), поэтому я подумал, что будет сложно запустить только одно глобальное приложение, которое управляет итерацией всех пользователей

5. Можете ли вы точно сказать нам, что должен делать скрипт?

Ответ №1:

Возможно, вы захотите проверитьhttps://www.npmjs.com/package/python-shell Вы можете создать экземпляр python на узле.

Комментарии:

1. Хммм, это может сработать. Я постараюсь лучше разобраться в .send() этом, возможно, это то, что я ищу

2. Это сработало, я использовал .send() , как я уже сказал. Я только что создал условие, которое позволяет клиенту вводить данные, когда ему отправляется определенное сообщение. Затем я передаю это сообщение от клиента на websocket, а с websocket на python, используя .send() из python-shell библиотеки 🙂

3. Рад, что это помогло! Удачного кодирования 🙂