Reputation: 1
Q: I have a flask server application by flask-socketio, it is :
from flask import Flask
from flask_socketio import SocketIO
app = Flask(__name__)
# CORS(app, supports_credentials=True)
app.config['SECRET_KEY'] = 'ztyzjbnb'
sio = SocketIO(app, cors_allowed_origins="*") # cors_allowed_origins 允许跨域访问socket
def loop_counter(json_data):
while True:
sio.emit('main_ctrl', json_data)
loop_counter({"one": 1, "two": 2, "three": 3})
@app.route('/')
def hello_world(): # put application's code here
return 'Hello World!'
@sio.on('connect establish event')
def handle_connect_establish_socket(msg):
print('connection established with message : "%s"' % msg)
if __name__ == '__main__':
sio.run(app, host='0.0.0.0', port=5000, debug=True)
but I dont connect this server on python-socketio.Client. this client application code is :
import socketio
import time
# create
sio = socketio.Client()
# connect success
@sio.event
def connect():
print('Connection established')
sio.emit('message', 'Hello, Server!')
# message
@sio.event
def response(data):
print(f'Received response: {data}')
# dis
@sio.event
def disconnect():
print('Disconnected from server')
# error
@sio.event
def connect_error(data):
print(f'Connection error: {data}')
# connect to server
try:
# polling
sio.connect('http://localhost:5000', transports=['polling'])
print('Connected to server using polling transport')
# keepLive
while True:
time.sleep(1)
except Exception as e:
print(f'Failed to connect to server: {e}')
finally:
# dis connect
sio.disconnect()
print('Disconnected from server')
client can connect server's network. But server no anymore message send to client. If javascript's socketio connect to server, as time, flask will send messsage to javascript client and python client.javascript application code is:
angular.module('texture_ui', ['ngFileUpload'])
.controller('MainCtrl', function($scope, $http, Upload){
$scope.socket = io.connect($scope.server_ip);
$scope.socket.on('connect', function(){
$scope.socket.emit('connect establish event', {data: 'connection established...'})
});
$scope.version = '^_^';
$scope.socket.on('main_ctrl', function(data) {
$scope.mc_data = data;
if(data.app_version){
$scope.version = data.app_version;
}
}
requirement.txt
Flask==0.12.2
Flask_SocketIO==4.2.1
werkzeug==2.0.3
python-socketio==4.4.0
python-engineio==3.11.2
websocket-client==1.2
Q: I want to know why ?
I used the engineio.Client subclass instead of socketio.Client, but later found an error with an invalid connection type. Then, using the engineio.Client inheritance class, the request appears differently than the frontend long-lived connection request. After forcing the sio connection to stay connected, the python client was able to connect to the server, but the data was still unavailable
Upvotes: 0
Views: 34
Reputation: 8542
Your sending loop blocks the entire server. If you outsource it to a background thread you can get around this.
Furthermore, the server is sending all the time. This makes it difficult for the client to connect.
The following code shows how you can establish a successful connection in different ways.
from flask import Flask, request, render_template_string
from flask_socketio import SocketIO
import time
def update_task(data):
while True:
sio.emit('main_ctrl', data)
time.sleep(0.5)
app = Flask(__name__)
app.secret_key = 'your secret here'
sio = SocketIO(app, cors_allowed_origins='*')
sio.start_background_task(update_task, {'one': 1, 'two': 2, 'three': 3})
@app.route('/')
def index():
return render_template_string('''
<script
src="https://cdn.socket.io/4.8.1/socket.io.min.js"
integrity="sha384-mkQ3/7FUtcGyoppY6bz/PORYoGqOl7/aSUMn2ymDOJcapfS6PHqxhRTMh1RR0Q6+"
crossorigin="anonymous"></script>
<script>
(function() {
const sock = io.connect('http://localhost:5000/');
sock.on('connect', () => {
sock.emit('message', 'Hello Server!');
});
sock.on('main_ctrl', (data) => {
console.log(data);
});
})();
</script>
''')
@sio.on('connect')
def handle_connect():
print(f'connect: {request.sid}')
@sio.on('disconnect')
def handle_disconnect():
print(f'disconnect: {request.sid}')
@sio.on('message')
def handle_message(data):
print(f'message: {data}')
if __name__ == '__main__':
sio.run(app, host='0.0.0.0', port=5000, debug=True)
import socketio
import time
sio = socketio.Client()
@sio.event
def connect():
print('Connection established')
sio.emit('message', 'Hello, Server!')
@sio.event
def disconnect():
print('Disconnected from server')
@sio.event
def connect_error(data):
print(f'Connection error: {data}')
@sio.event
def main_ctrl(data):
print('>_', data)
try:
# If the slash is not part of the URL, specifying the namespace is essential.
sio.connect('http://localhost:5000', transports=['polling'], namespaces=['/'])
print('Connected to server using polling transport')
while True:
time.sleep(1)
except Exception as e:
print(f'Failed to connect to server: {e}')
finally:
sio.disconnect()
print('Disconnected from server')
Upvotes: 0