【问题标题】:Flask read socket烧瓶读取套接字
【发布时间】:2013-05-23 06:57:20
【问题描述】:

我已经使用烧瓶创建了一个 Web 服务。现在,事实证明我必须在同一个应用程序中支持一些套接字连接。

我尝试使用特定的网址,然后从

request.stream

请求在哪里

from flask import request

数据在那里,但我得到了code 400, message Bad request

我能做些什么来解决这个问题吗?或者可能有做其他事情的想法。

【问题讨论】:

  • 您是否正在运行带有 debug=True 的 Flasks 内置网络服务器?可能会给你一些调试输出,因为 400 的描述性不是很强:)。
  • 我并不完全清楚您要完成什么。你想为你的应用打开一个 JS 套接字吗?或者让应用程序打开一个到其他服务器的套接字?还是写一些数据到Flask已经对http客户端开放的socket?
  • 您是否尝试提供 Websockets 作为传输媒介?
  • 不,我不想要网络套接字。我只想让视图监听传入的套接字连接。

标签: python flask python-sockets


【解决方案1】:

据我所知,您想听一个套接字吗?您不应该为此使用烧瓶,它会尝试解析 HTTP 标头和正文(如果适用),这解释了 400 错误请求。

您应该看看SocsketServer 模块。

【讨论】:

  • 好的。但是我可以使用烧瓶将此服务器映射到特定的 url 吗?示例@app.route('/socket') 并在视图内部处理套接字?
  • 除非您计划在该套接字上使用 HTTP,否则不会。该流无论如何都不适用于双向通信,因为它前面有 wsgi 和可选的网络服务器。
  • 现在我明白为什么我没有在互联网上找到类似的东西了。
【解决方案2】:

你可以使用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,)

【讨论】:

    猜你喜欢
    • 2018-09-18
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多