Flask Socket.io не работает при излучении из потока - PullRequest
0 голосов
/ 08 апреля 2019

Описание

На стороне клиента есть 2 кнопки:

  • Один заставляет сервер отправлять периодические сообщения
  • Другой, останавливает отправку периодических сообщений

Эта проблема является показателем реальной проблемы, которую я пытаюсь решить.

Я создаю приложение, и на стороне сервера оно, похоже, работает, но клиент не получает push-запрос сервера, но может запустить его и уничтожить!

Что я пытался

Сторона сервера

import random
from threading import Thread
from time import sleep

from flask import Flask
from flask_socketio import SocketIO

SOCKET_NAMESPACE = '/test'

is_pushing = False

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!!'
socketio = SocketIO(app)


def server_push(fps):
    dt = 1 / fps
    global is_pushing
    while is_pushing:
        with app.test_request_context('/'):
            sent = f"Server Pushed!! {random.random()}"
            print(sent)
            socketio.emit("serverResponse", sent, namespace=SOCKET_NAMESPACE)
            sleep(dt)


@socketio.on('connect', namespace=SOCKET_NAMESPACE)
def on_connect():
    print("connected server!!")
    socketio.emit("serverResponse", "First Push", namespace=SOCKET_NAMESPACE)


@socketio.on('disconnect', namespace=SOCKET_NAMESPACE)
def on_disconnect():
    print("disconnected server!!")


@socketio.on('startServerPush', namespace=SOCKET_NAMESPACE)
def on_start_server_push(fps=1):
    print("Sever push start!!")
    global is_pushing
    is_pushing = True
    socketio.emit("serverResponse", "Start Push", namespace=SOCKET_NAMESPACE)
    Thread(target=lambda: server_push(fps)).start()


@socketio.on("killServerPush", namespace=SOCKET_NAMESPACE)
def on_kill_server_push():
    print("Server push stop!!")
    global is_pushing
    is_pushing = False
    socketio.emit("serverResponse", "Kill Push", namespace=SOCKET_NAMESPACE)


def main():
    socketio.run(app, port=8082, debug=True)


if __name__ == '__main__':
    main()

Клиентская сторона

import openSocket from 'socket.io-client';
import React, { Component } from 'react';

class Test extends Component {
  state = {
    pushedFromServer: [],
    socket: null
  };

  componentDidMount() {
    const url = 'localhost:8082/test';
    const socket = openSocket(url);
    socket.on('connect', () => console.log('Test connected!!'));
    socket.on('disconnect', () => console.log('Test disconnected!!'));
    socket.on('serverResponse', response => {
      console.log(response);
      const pushedFromServer = [...this.state.pushedFromServer];
      pushedFromServer.push(response);
      this.setState({ pushedFromServer });
    });
    this.setState({ socket });
  }

  killServerPush = () => {
    this.state.socket.emit('killServerPush');
  };

  startServerPush = () => {
    this.state.socket.emit('startServerPush');
  };

  render() {
    return (
      <div>
        <button onClick={this.startServerPush}>
          <h3>Start push from server</h3>
        </button>
        <button onClick={this.killServerPush}>
          <h3>Kill push from server</h3>
        </button>
        <ul>
          {this.state.pushedFromServer.map(value => (
            <li>{value}</li>
          ))}
        </ul>
      </div>
    );
  }
}

export default Test;

Заключительные замечания

В клиенте я мог получить First Push и Start Push , я также могу остановить периодический процесс на клиенте и перезапустить его. Я не могу получать периодические сообщения на клиенте .

Спасибо

1 Ответ

0 голосов
/ 08 апреля 2019

Посмотрев на https://github.com/miguelgrinberg/python-socketio/issues/99, я нашел решение проблемы.

Просто нужно изменить сторону сервера.

Изменить строку:

Thread(target=lambda: server_push(fps)).start()
*От 1009 * до
 socketio.start_background_task(target=lambda: server_push(fps))

И вместо использования python sleep используйте:

socketio.sleep(dt)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...