Reputation: 657
The client side has 2 buttons:
This problem is a proxy of the real problem I am trying to solve.
I build the app, and in the server side it seems to work, but the client doesn't receive the server push, but is able to start the push and kill it!
Server Side
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()
Client Side
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;
In the client, I could receive the First Push, and the Start Push, I am also able to stop the periodic process from the client and restart it. I am not able to receive the periodic messages on the client.
Thanks
Upvotes: 3
Views: 4656
Reputation: 657
By looking at https://github.com/miguelgrinberg/python-socketio/issues/99, I found a solution to the issue.
Just need to change the server side.
Change line:
Thread(target=lambda: server_push(fps)).start()
to
socketio.start_background_task(target=lambda: server_push(fps))
And instead of using python sleep, use:
socketio.sleep(dt)
Upvotes: 3