简体   繁体   中英

Why is my asynchronous (NodeJS-Python) WebSocket not connecting immediately?

This is a continuation of a question I had earlier, Using Socket IO and aiohttp for data transfer between node JS and Python , based on this tutorial, https://tutorialedge.net/python/python-socket-io-tutorial/ .

I have an asynchronous tunnel that connects a Node JS client ( send.js ) and a python server ( receive.py ). Right now send.js outputs a random number and then sends it to the Python server ( receive.py ), which then sends the message back to the JS client.

The setup works, however, it takes a couple minutes for the server to start receiving data from send.js , and I do not know why.

The Node JS script will output data, but the server will not receive it for at least a couple minutes and even after it starts receiving data, it does not receive the data it did not get earlier, it will only receive the data from the moment the server and client can finally connect.

I am not sure if this has something to with the Python side, Node JS side, or something else.

I am using Node 8.16.1 and Python 3.7.3

The code is below:

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)

Let me know if more information is needed.

I don't know if you have to use the packages that you are using but here is my working version with ws package for node and asyncio and websockets packages for python. Have fun and nice question.

send.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())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM