Flask-SocketIO не может генерировать событие напрямую, используя функцию emit () - PullRequest
0 голосов
/ 03 ноября 2018

Я пытаюсь соединить приложение React и приложение Flask, используя SocketIO, и столкнулся с проблемой, которую не могу понять. Приложение простое, поскольку оно меняет цвет фона страницы на обеих вкладках, если щелкнуть кнопку цвета в одной из них с помощью сокетов. Мой простой код для React и Flask выглядит следующим образом:

Структура

frontend/src/App.js 
backend/__init__.py
backend/socket_listeners.py
manage.py

App.js

import React, { Component } from 'react';
import io from 'socket.io-client';
import axios from 'axios';
import './App.css';



class App extends Component {

   constructor(props){
      super(props);
      this.state = {
        color: ''
      };

      this.socket = io(`http://${document.domain}:5000`);

      this.socket.on('receive_change_color', (color) => {
         document.body.style.backgroundColor = color;
      });

   }

   send = (e) => {
     e.preventDefault();
     console.log("emitting", this.state.color);
     this.socket.emit('send_change_color', this.state.color);
   }

   setColor = (color) => {
     this.setState({color: color});
   }

   componentDidMount() {
      axios.get("http://localhost:5000/sample")
       .then((res) => {
        console.log(res);
      })
      .catch((e) => {
        console.log(e);
      });
   }

  render() {

      return (
         <div style={{ textAlign: "center"}}>
            <button onClick={(e) => this.send(e)}>Change color</button>
            <button id="blue" onClick={()=>this.setColor('blue')}>Blue</button>
            <button id="red" onClick={() => this.setColor('red')}>Red</button>
         </div>
      );
    }
 }

export default App;

__ __ INIT. Ру

from flask import Flask
from flask_cors import CORS
from backend.controllers.api import api
from backend import assets
from backend.models import db

from backend.extensions import (
    cache,
    debug_toolbar,
    login_manager,
    migrate,
)

def create_app(object_name):
    app = Flask(__name__)
    app.config.from_object(object_name)
    CORS(app, resources={r"/*":{"origins":"*"}})
    cache.init_app(app)
    debug_toolbar.init_app(app)
    db.init_app(app)
    migrate.init_app(app, db)
    login_manager.init_app(app)
    app.register_blueprint(api)
    return app

socket_listeners.py

import os
from backend import create_app
from flask_socketio import  SocketIO, join_room, leave_room, emit

env = os.environ.get('BACKEND_ENV', 'dev')
app = create_app('backend.settings.%sConfig' % env.capitalize())

socketio = SocketIO(app)

@socketio.on('connect')
def connect():
   emit('connect', {'data': "sample"})

@socketio.on('disconnect')
def disconnect():
   print("Disconnected to socket!")

@socketio.on('send_change_color')
def change_color(color):
    print("Color: ", color)
    emit('receive_change_color', color) **this doesnt work**
    # socketio.emit('receive_change_color', color) **this works**

manage.py

#!/usr/bin/env python
import os
from flask import current_app
from flask_script import Manager, Server
from flask_script.commands import ShowUrls, Clean
from flask_migrate import MigrateCommand
from backend.socket_listeners import socketio, app
from flask_socketio import join_room, leave_room, emit
from backend import create_app
from backend.models import db, User

manager = Manager(app)
manager.add_command("server", Server(threaded=True))
manager.add_command("show-urls", ShowUrls())
manager.add_command("clean", Clean())
manager.add_command("db", MigrateCommand)

@manager.shell
def make_shell_context():
   return dict(app=app, db=db, User=User)

@manager.command
def createdb():
    db.drop_all()
    db.create_all()

@manager.command
def runsocket():
    socketio.run(
       app,
       host="0.0.0.0"
    )

if __name__ == "__main__":
    manager.run()

Как показано в socket_listeners.py последняя строка в change_color , функция socketio.emit () работает, но строка над ней - нет. Согласно документации метод emit () должен работать напрямую, но я не могу изменить цвет в интерфейсе или отправьте recieve_change_color, используя метод emit () напрямую.

Есть идеи, что мне здесь не хватает?

...