使用套接字IO和aiohttp在节点JS和Python之间进行数据传输

时间:2019-04-22 01:24:33

标签: javascript python node.js http aiohttp

我的总体目标是在JavaScript文件(使用node运行)中生成随机数流,并在异步时间间隔内将其发送到python脚本。一旦数字在python中,脚本将确定数字是否为偶数。如果是,则将这些数字发送回JavaScript文件。我的主要重点是获取JavaScript和Python之间的通信。

一旦启动JavaScript文件和python服务器,它们将继续运行,直到我停止它们为止。

当前,我正在研究位于此处(https://tutorialedge.net/python/python-socket-io-tutorial/)的教程。本教程将Socket 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 ( How to rewrite same random after random interval)

下面显示的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时,随机数将以随机间隔连续生成,并且可以在终端中看到输出。但是我没有在服务器端得到响应。

我认为该问题与以下两个问题有关:

首先,我当前的JS代码( index.js )最初是一个HTML脚本,该脚本通过单击“ http://localhost:8080 ”上的按钮单击来发送消息。 ”我将该脚本调整为JS脚本,并添加了其他功能。因此,在我设置套接字io的 index.js 的以下几行中可能存在问题:

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

为清楚起见,这是 index.js 基于的原始html代码( index.html ):

<!-- 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转换(Syntax error when trying to convert HTML file to JavaScript containing socket io, SyntaxError: Unexpected token <)相关的问题

第二,因为本教程最初使用的是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 )将使用套接字io将数据发送到python服务器( server.py ),而python服务器将使用aiohttp,将把分析后的数据发送回相同的JS脚本。这将连续发生,直到手动停止其中一个脚本为止。

如果需要任何澄清,请随时询问。

1 个答案:

答案 0 :(得分:1)

我相信,在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 }