我已经使用烧瓶创建了一个 Web 服务。现在,事实证明我必须在同一个应用程序中支持一些套接字连接。
我尝试使用特定的网址,然后从
request.stream
请求在哪里
from flask import request
数据在那里,但我得到了code 400, message Bad request。
我能做些什么来解决这个问题吗?或者也许是做其他事情的想法。
我已经使用烧瓶创建了一个 Web 服务。现在,事实证明我必须在同一个应用程序中支持一些套接字连接。
我尝试使用特定的网址,然后从
request.stream
请求在哪里
from flask import request
数据在那里,但我得到了code 400, message Bad request。
我能做些什么来解决这个问题吗?或者也许是做其他事情的想法。
据我从您的评论中可以看出,您想听一个套接字吗?您不应该为此使用烧瓶,它会尝试解析 HTTP 标头和正文(如果适用),这解释了 400 错误请求。
您应该看一下SocsketServer模块。
你可以使用flask-socketio:https ://flask-socketio.readthedocs.io/en/latest/
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
if __name__ == '__main__':
socketio.run(app)
它必须向客户端提供一个页面:
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('connect', function() {
socket.emit('my event', {data: 'I\'m connected!'});
});
</script>
然后通过事件处理数据:
@socketio.on('my event')
def handle_my_custom_event(json):
print('received json: ' + str(json))
# send(json, json=True) # send data back to client
# emit('my response', json) # another way to send data back to client
# emit('my response', ('foo', 'bar', json)) # multiple arguments via tuple
return 'one', 2 # yet another way to send data back to client
定义事件时,您还可以接收纯字符串数据、有参数等。
@socketio.on('my_event')
def handle_my_custom_event(arg1, arg2, arg3):
print('received args: ' + arg1 + arg2 + arg3)
如果服务器需要在没有沉淀请求的情况下广播消息:
def some_function():
socketio.emit('some event', {'data': 42})
您还可以创建房间来对客户进行分组。
from flask_socketio import join_room, leave_room
@socketio.on('join')
def on_join(data):
username = data['username']
room = data['room']
join_room(room)
send(username + ' has entered the room.', room=room)
@socketio.on('leave')
def on_leave(data):
username = data['username']
room = data['room']
leave_room(room)
send(username + ' has left the room.', room=room)
并且有内置的连接事件:
from flask_socketio import ConnectionRefusedError
@socketio.on('connect')
def test_connect():
emit('my response', {'data': 'Connected'})
@socketio.on('disconnect')
def test_disconnect():
print('Client disconnected')
@socketio.on('connect')
def connect():
if not self.authenticate(request.args):
raise ConnectionRefusedError('unauthorized!')
和日志记录/异常处理:
socketio = SocketIO(logger=True, engineio_logger=True)
@socketio.on_error() # Handles the default namespace
def error_handler(e):
pass
@socketio.on_error('/chat') # handles the '/chat' namespace
def error_handler_chat(e):
pass
@socketio.on_error_default # handles all namespaces without an explicit error handler
def default_error_handler(e):
print(request.event["message"]) # "my error event"
print(request.event["args"]) # (data,)