Использование Socket IO и aiohttp для передачи данных между узлом JS и Python - PullRequest
0 голосов
/ 22 апреля 2019

Моя общая цель - создать поток случайных чисел в файле JavaScript (который запускается с использованием узла) и отправить их в скрипт Python через асинхронные промежутки времени.Как только числа в Python, сценарий определит, являются ли числа четными или нет.Если они есть, числа отправляются обратно в файл JavaScript.Моя основная задача - получить связь между JavaScript и Python.

Как только я начну файл JavaScript и сервер python, они продолжат работать, пока я не остановлю их.

В настоящее время я работаю над учебником, расположенным здесь (https://tutorialedge.net/python/python-socket-io-tutorial/). В учебнике используется сокет io для JS и aiohttp для python.

Я манипулировал html-кодом в JSкод ( index.js ), который приведен ниже:

// index.js    
var socket = require('socket.io-client')('http://localhost:8080');
socket.on('connect', function(){});

function generateNumber() {
   let n = Math.floor(Math.random() * 50);
   let json = {
       'number': n
   }
   console.log(json);
   return json;
}

(function loop() {
    var rand = Math.round(Math.random() * (3000 - 500)) + 500;
    setTimeout(function() {
            generateNumber();
            loop();  
    }, rand);
}());

function sendMsg() {
  socket.emit("message", generateNumber());
}

socket.on("message", function(data) {
console.log(data);
});

Я создал функцию (generateNumber) для создания случайных чисел, выводимых в формате JSON. Я использую JSON, потому что я верю в этопозволит легко преобразовывать данные в списки и целые числа, когда числа достигают скрипта Python. Функция цикла позволяет непрерывно создавать числа через произвольные интервалы и была взята отсюда: Randomize setInterval (Как переписать одно и то же случайное числопосле случайного интервала)

Сервер Python ( server.py ), показанный ниже, был взят из учебника (https://tutorialedge.net/python/python-socket-io-tutorial/):

# server.py
from aiohttp import web
import socketio

# creates a new Async Socket IO Server
sio = socketio.AsyncServer()
# Creates a new Aiohttp Web Application
app = web.Application()
# Binds our Socket.IO server to our Web App
# instance
sio.attach(app)

# we can define aiohttp endpoints just as we normally
# would with no change
async def index(request):
    with open('index.html') as f:
        return web.Response(text=f.read(), content_type='text/html')

# If we wanted to create a new websocket endpoint,
# use this decorator, passing in the name of the
# event we wish to listen out for
@sio.on('message')
async def print_message(sid, message):
    # When we receive a new event of type
    # 'message' through a socket.io connection
    # we print the socket ID and the message
    print("Socket ID: " , sid)
    print(message)

# We bind our aiohttp endpoint to our app
# router
app.router.add_get('/', index)

# We kick off our server
if __name__ == '__main__':
    web.run_app(app)

По состоянию натеперь, когда я запускаю node index.js, случайные числа непрерывно генерируются через случайные интервалы, и вывод можно увидеть в терминале. Но я не получаю ответ на сервере side.

Я полагаю, что проблема связана со следующими 2 проблемами:

Во-первых, мой текущий код JS ( index.js ) изначально был html-скриптом, который отправлял сообщение с щелчком кнопки, размещенным на «http://localhost:8080.”. Я настроил скрипт как JS-скрипт, а также добавил дополнительные функции.Таким образом, может быть проблема в следующих строках index.js , где я устанавливаю сокет io:

var socket = require('socket.io-client')('http://localhost:8080');
socket.on('connect', function(){});

Для ясности, вот исходный HTML-код ( index.html ), основанный на index.js :

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <button onClick="sendMsg()">Hit Me</button>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    <script>
      const socket = io("http://localhost:8080");

      function sendMsg() {
        socket.emit("message", "HELLO WORLD");
      }
    </script>
  </body>
</html>

Я также задал предыдущий вопрос, связанный с преобразованием html в JS ( Синтаксическая ошибка при попыткепреобразовать HTML-файл в JavaScript, содержащий сокет io, SyntaxError: неожиданный токен <</a>)

Во-вторых, поскольку в учебном пособии изначально использовался html-файл, а не JS, я считаю, что скрипт python ( server.py)) все еще ожидает вывода из html-скрипта, поэтому я думаю, что эти строки в server.py необходимо изменить:

async def index(request):
    with open('index.html') as f:
        return web.Response(text=f.read(), content_type='text/html')

Но я не уверен, как сделатьправильные изменения, у меня проблемы с поиском ссылок на мой вопрос на сайте aiohttp (https://aiohttp.readthedocs.io/en/stable/),, или я не уверен в том, что я ищу.

Оба server.py и index.js в настоящее время работают без ошибок, но онине общаются.

В целом, файл JS ( index.js ) будет отправлять данные на сервер Python ( server.py ) с использованием сокета io и сервера Python,используя aiohttp, будет отправлять проанализированные данные в тот же JS-скрипт.Это будет происходить непрерывно до тех пор, пока один из сценариев не будет остановлен вручную.

Если вам необходимо что-либо разъяснить, пожалуйста, не стесняйтесь спрашивать.

1 Ответ

1 голос
/ 22 апреля 2019

Я считаю, что в части JS вы должны вызвать куда-нибудь sendMsg () для отправки сообщения.

Обновлено

const io = require('socket.io-client');

const socket = io('http://localhost:8080');

socket.on('message', data => {
  console.log('Got from server: ');
  console.log(data);
});

function generateNumber() {
  const n = Math.floor(Math.random() * 50);
  return { number: n };
}

function sendMsg() {
  const json = generateNumber();
  console.log('Sending to server:');
  console.log(json);

  socket.emit('message', json);
}

function loop() {
  const rand = Math.round(Math.random() * (3000 - 500)) + 500;
  console.log(`Setting timeout ${rand}ms`);
  setTimeout(() => {
    sendMsg();
    loop();
  }, rand);
}

socket.on('connect', () => {
  console.log('Connected to server');
  loop();
});

Я использовал узел с обеих сторон.Серверная сторона просто отправляет обратно каждое полученное сообщение.Логи выглядят так:

Connected to server
Setting timeout 1685ms
Sending to server:
{ number: 21 }
Setting timeout 1428ms
Got from server: 
{ number: 21 }
Sending to server:
{ number: 40 }
Setting timeout 2955ms
Got from server: 
{ number: 40 }
...