3

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.

W. Churchill
  • 346
  • 1
  • 7
  • 28

1 Answers1

2

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())
C.Gochev
  • 1,837
  • 11
  • 21
  • Is the line `ws.send(json)` in send.js, the line that is used by `data = await websocket.recv()` in receive.py to obtain values through the web socket? So this is something built into ws where `websocket.recv()` always looks for values from `ws.send()`? – W. Churchill Jan 28 '20 at 22:37
  • The `Websocket`protocol basically at the lowest level has the ability to send data and to listen for data(recieve). The packages you were using have more abstractions build on top that is why you could `emit` and listen for different events. `ws` package and `websockets` are more barebones and that is why I prefer them.Here you can learn more about the `Websocket` protocol https://tools.ietf.org/html/rfc6455 – C.Gochev Jan 28 '20 at 22:49