Flask Socket.io从线程发出时不起作用

时间:2019-04-08 11:53:18

标签: python multithreading flask socket.io

说明

客户端有2个按钮:

  • 一个使服务器发送定期消息
  • 另一个,停止发送定期消息

此问题是我要解决的实际问题的代理。

我构建了该应用程序,并且在服务器端似乎可以运行,但是客户端没有收到服务器推送,但是能够启动推送并杀死它!

我尝试过的

服务器端

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 :(得分:0)

通过查看https://github.com/miguelgrinberg/python-socketio/issues/99,我找到了解决该问题的方法。

只需更改服务器端即可。

更改行:

Thread(target=lambda: server_push(fps)).start()

 socketio.start_background_task(target=lambda: server_push(fps))

而不是使用python sleep,请使用:

socketio.sleep(dt)