Почему мой асинхронный (NodeJS - Python) WebSocket не подключается сразу? - PullRequest
3 голосов
/ 24 января 2020

Это продолжение вопроса, который у меня был ранее, Использование Socket IO и aiohttp для передачи данных между node JS и Python, на основе этого урока https://tutorialedge.net/python/python-socket-io-tutorial/.

У меня есть асинхронный туннель, который соединяет клиент Node JS ( send. js) и сервер python ( receive.py ) , Прямо сейчас send. js выводит случайное число, а затем отправляет его на сервер Python ( receive.py ), который затем отправляет сообщение обратно клиенту JS.

Настройка работает, однако серверу требуется несколько минут, чтобы начать получать данные из send. js, и я не знаю почему.

Сценарий Node JS будет выводить данные, но сервер не получит их как минимум пару минут, и даже после того, как он начнет получать данные, он не получит данные, которые он не получил ранее, он будет получать данные только с момента, когда сервер и клиент могут наконец подключиться.

Я не уверен, имеет ли это отношение со стороной Python, Node JS или чем-то еще.

Я использую Node 8.16.1 и Python 3.7.3

Код ниже:

send. js

const io = require('socket.io-client');
const socket = io('http://localhost:8080');

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

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;
  setTimeout(() => {
    sendMsg();
    loop();
  }, rand);
}

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

receive.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)

# 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)
    await sio.emit('reply', message)

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

Дайте мне знать, если требуется дополнительная информация.

1 Ответ

2 голосов
/ 28 января 2020

Я не знаю, нужно ли вам использовать пакеты, которые вы используете, но вот моя рабочая версия с пакетом ws для узла и пакетами asyncio и websockets для python. Удачи и хороший вопрос.

отправить. js

const WebSocket = require('ws');


const ws = new WebSocket('ws://localhost:8080')
console.log(ws)

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

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

  ws.send(json);
}

function loop() {
  setTimeout(() => {
    sendMsg();
    loop();
  }, 5000);
}
ws.on('open', function open() {
  console.log('connect')
  console.log(ws)
  loop()

})

ws.on('message', function(data) {
  console.log(data)
})

receive.py

import asyncio
import websockets

async def start(websocket, path):
    print("connected")
    while True:
       data = await websocket.recv()
       print(f"< {data}")
       await websocket.send(data)

async def main():
    server = await websockets.serve(start, 'localhost', 8080)
    await server.wait_closed()
asyncio.run(main())
...