问:我有一个 Flask-socketio 的 Flask 服务器应用程序,它是 :
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)
但我没有在 python-socketio.Client 上连接此服务器。该客户端应用程序代码是:
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')
客户端可以连接服务器的网络。但服务器不再向客户端发送消息。如果javascript的socketio连接到服务器,随着时间的推移,flask将向javascript客户端和python客户端发送消息。javascript应用程序代码是:
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;
}
}
需求.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
问:我想知道为什么?
我使用了engineio.Client子类而不是socketio.Client,但后来发现连接类型无效的错误。然后,使用engineio.Client继承类,请求的显示方式与前端长期连接请求不同。强制sio连接保持连接后,python客户端能够连接到服务器,但数据仍然不可用
您的发送循环阻塞了整个服务器。如果您将其外包给后台线程,您可以解决这个问题。
此外,服务器一直在发送。这使得客户端很难连接。
以下代码展示了如何通过不同方式建立成功的连接。
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')