flask-socketio 服务器未通过轮询连接到 python-socketio 客户端

问题描述 投票:0回答:1

问:我有一个 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客户端能够连接到服务器,但数据仍然不可用

flask socket.io flask-socketio python-socketio
1个回答
0
投票

您的发送循环阻塞了整个服务器。如果您将其外包给后台线程,您可以解决这个问题。
此外,服务器一直在发送。这使得客户端很难连接。

以下代码展示了如何通过不同方式建立成功的连接。

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')
© www.soinside.com 2019 - 2024. All rights reserved.