【问题标题】:Flask Socket.io doesn't work when emitting from thread从线程发射时,Flask Socket.io 不起作用
【发布时间】:2019-04-08 11:53:17
【问题描述】:

说明

客户端有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 PushStart Push,我也可以从客户端停止周期性进程并重新启动它。 我无法在客户端接收定期消息

谢谢

【问题讨论】:

    标签: python multithreading flask socket.io


    【解决方案1】:

    通过查看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)
    

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 1970-01-01
      • 2016-12-21
      • 2021-08-14
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多