标签: flask-socketio

flask-socketio每个用户一个房间?昂贵?

我有一个运行pandas的烧瓶webapp,可以在后端进行一些数据分析.

现在,我采用了朴素的方法,使用AJAX让用户将查询发送回服务器并与数据进行交互.但事实证明每个请求都有很多开销,每次我需要将数据重新加载到pandas/memory中,这是非常重复的.

我认为socketio在这里很有用 - 我会打开一个套接字连接,这样一旦文件加载到pandas中,用户就可以通过套接字以更少的开销响应性地交互和查询数据.

所以我现在的问题是:

  • 我应该为每个用户打开一个房间,因为用户不需要互相交流吗?
  • 这是否规模 - 为每个用户开放一个房间?
  • 命名空间在哪里适合?我是否将命名空间分配给网站的不同部分,并进一步为每个用户打开每个命名空间下的空间?
  • 或者我应该生成一个猴子修补线程?每个用户的Greenlet?

flask socket.io pandas gevent-socketio flask-socketio

5
推荐指数
1
解决办法
952
查看次数

Heroku sock =后端服务器请求因Flask SocketIO应用程序而中断

我有一个使用以下Procfile托管在heroku上的flask-socketio应用程序:

web: gunicorn --worker-class eventlet hello:app
Run Code Online (Sandbox Code Playgroud)

自从我切换到socketio后,该应用程序一直表现得不一致.之前该应用程序将运行一段时间,然后POST请求将开始超时.

从昨天晚上起,我一直收到错误

sock=backend at=error code=H18 desc="Server Request Interrupted" method=GET path="/static/js/third-party/browser.js" host=deard.herokuapp.com request_id=725da6af-aa29-4293-a411-2c89977f1d4d fwd="216.165.95.0" dyno=web.1 connect=1ms service=36ms status=503 bytes=13811
Run Code Online (Sandbox Code Playgroud)

我阅读了heroku错误代码说明,其中说明"在后端返回HTTP响应之前,属于您应用程序的Web进程的后端套接字已关闭".

但我不知道为什么会发生这种情况.

关于我应该注意什么的任何线索,将帮助我调试这个.

我可以共享代码,但它的300行很长,因为我不知道错误源自何处,我不确定它是否有用.

python heroku flask flask-socketio

5
推荐指数
1
解决办法
1576
查看次数

为什么这会降低音频质量?

我正在将烧录应用程序中的音频从客户端传输到服务器,但收到的音频质量非常低.

在客户端,我按如下方式预处理音频缓冲区:

this.node.onaudioprocess = function(e){
      var buf = e.inputBuffer.getChannelData(0);
      var out = new Int16Array(buf.length);
      for (var i = 0; i < buf.length; i++){
        var s = Math.max(-1, Math.min(1, buf[i]));
        out[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
      }
      socket.emit('audio event',{data: out})
      return;
}
Run Code Online (Sandbox Code Playgroud)

在服务器端,我收到如下音频:

audio_file = open('tempfile.raw', 'w')

@socketio.on('audio event')
def audio_message(message):
    dat = [v[1] for v in sorted(message['data'].iteritems())]
    n = len(dat)
    byteval = struct.pack('<'+str(n)+'h',*dat)
    audio_file.write(byteval)
Run Code Online (Sandbox Code Playgroud)

但由此产生的音频听起来很金属,中断和嘈杂.以下是结果波形的外观:

收到波浪样本

在我的代码中,音频质量丢失了吗?如何在没有质量损失的情况下传输音频?

javascript audio pack flask flask-socketio

5
推荐指数
1
解决办法
146
查看次数

在Python和Eventlet中使用多个核心

我有一个Python Web应用程序,客户端(Ember.js)通过WebSocket与服务器通信(我正在使用Flask-SocketIO).除了WebSocket服务器之外,后端还有两件值得提及的事情:

当客户端提交图像时,在数据库中创建其实体,并将id放入图像转换队列中.工人抓住它并进行图像转换.之后,工作人员将其放入OCR队列,在那里它将由OCR队列工作者处理.

到现在为止还挺好.WS请求在不同的线程中同步处理(Flask-SocketIO使用Eventlet),并且繁重的计算操作异步发生(在单独的线程中也是如此).

现在问题是:整个应用程序在Raspberry Pi 3上运行.如果我没有使用它的4核,我只有一个主频为1.2 GHz的ARMv8内核.这对于OCR来说是非常小的力量.所以我决定了解如何在Python中使用多个内核.虽然我读到了GIL的问题但是我发现了多处理的地方The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads..正是我想要的.所以我立即取代了

from threading import Thread
thread = Thread(target=heavy_computational_worker_thread)
thread.start()
Run Code Online (Sandbox Code Playgroud)

通过

from multiprocessing import Process
process = Process(target=heavy_computational_worker_thread)
process.start()
Run Code Online (Sandbox Code Playgroud)

队列需要由多个核心处理,所以我不得不改变

from queue import Queue
queue = multiprocessing.Queue()
Run Code Online (Sandbox Code Playgroud)

import multiprocessing
queue = multiprocessing.Queue()
Run Code Online (Sandbox Code Playgroud)

同样.有问题:队列和线程库由Eventlet …

python multithreading multiprocessing eventlet flask-socketio

5
推荐指数
1
解决办法
992
查看次数

gevent.hub.LoopExit异常:LoopExit('此操作将永远阻止',)

使用Websockets运行Flask应用程序时,总是出现此错误。我尝试遵循此指南-http://blog.miguelgrinberg.com/post/easy-websockets-with-flask-and-gevent

我有一个flask应用程序,为我的网络嗅探器提供GUI界面。嗅探器位于线程内,如下所示:(l是我的嗅探器线程; isRunning是一个布尔值,用于检查线程是否已在运行)

try:
    if l.isRunning == False:  # if the thread has been shut down
        l.isRunning = True  # change it to true, so it could loop again
        running = True
        l.start()  # starts the forever loop / declared from the top to be a global variable
        print str(running)
    else:
        running = True
        print str(running)
        l.start()
except Exception, e:
    raise e
return flask.render_template('test.html', running=running)  #goes to the test.html page
Run Code Online (Sandbox Code Playgroud)

嗅探器在没有socketio的情况下运行良好,我可以在遍历gui的同时嗅探网络。但是,当我在代码中包含socketio时,我首先看到socketio在索引页面中正常工作,并且能够接收来自服务器到页面。我还可以遍历GUI中的其他静态方法;但是,激活线程网络嗅探器会使浏览器挂断。我总是收到异常gevent.hub.LoopExit:LoopExit('此操作将永远阻止',)错误,当我重新运行程序时,控制台会说该地址已被使用。在我看来,这种情况可能无法正确关闭我的套接字。我还认为某些操作正在阻止该错误。我的python flask应用程序中的代码如下所示

def background_thread():
    """Example of how to send …
Run Code Online (Sandbox Code Playgroud)

python multithreading flask socket.io flask-socketio

4
推荐指数
2
解决办法
3856
查看次数

如何从websocket端点外部发出websocket消息?

我正在使用Flask构建一个网站,其中我也使用Flask-socketIO使用Websockets ,但有一点我不明白.

我建立了一个聊天功能.当一个用户发送消息时,我使用websockets将该消息发送到服务器,之后我从同一个调用中向另一个用户发送消息:

@socketio.on('newPM', namespace='/test')
@login_required_with_global
def io_newMessage(theJson):
    emit('message', {'message': theJson['message']}, room=str(theJson['toUserId']))
Run Code Online (Sandbox Code Playgroud)

但是,假设我想在保存文件时向用户发出消息.这意味着我需要从文件POST的视图中发出消息.所以根据flask_socketio文档,我可以在emit中添加一个名称空间.所以我写了这个:

@app.route('/doc', methods=['POST'])
@login_required
def postDoc():
    saveDocument(request.files['file'], g.user.id)
    emit('my response', {'data': 'A NEW FILE WAS POSTED'}, room=current_user.id, namespace='/test')
    return jsonify({'id': str(doc.id)})
Run Code Online (Sandbox Code Playgroud)

但是看到下面的堆栈跟踪仍然存在命名空间的问题; werkzeug有一个AttributeError: 'Request' object has no attribute 'namespace'.

有谁知道我在这里做错了什么?或者这是flask_socketio中的错误?欢迎所有提示!

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
    response …
Run Code Online (Sandbox Code Playgroud)

python websocket flask socket.io flask-socketio

4
推荐指数
1
解决办法
2693
查看次数

使用flask-migrate with flask-script,flask-socketio和application factory

我正在使用应用程序工厂方法创建一个烧瓶应用程序,但在使用带有socketio和flask-script的Flask-Migrate时出现问题.

问题是我将我的create_app功能传递给了Manager我,但我也需要传递app给我socketio.run().而现在我似乎无法找到解决方案.有什么方法可以将这两种解决方案结合起来吗?

manage.py:

#app = create_app(False)  <--- Old approach
#manager = flask_script.Manager(app) 

manager = flask_script.Manager(create_app)
manager.add_option("-t", "--testing", dest="testing", required=False)

manager.add_command("run", socketio.run(
    app,
    host='127.0.0.1',
    port=5000,
    use_reloader=False)
)

# DB Management
manager.add_command("db", flask_migrate.MigrateCommand)
Run Code Online (Sandbox Code Playgroud)

当我使用旧的方法与socketio,但没有烧瓶 - 迁移一切工作.如果我使用新方法,并删除socketio部分,迁移工作.

注意:我希望能够使用以下两个命令调用我的应用程序. python manage.py run python manage.py -t True db upgrade

编辑:

试着用current_app我的意思RuntimeError: working outside of application context

manager.add_command("run", socketio.run(
   flask.current_app,
   host='127.0.0.1',
   port=5000,
   use_reloader=False)
)
Run Code Online (Sandbox Code Playgroud)

flask flask-migrate flask-script flask-socketio

4
推荐指数
1
解决办法
1342
查看次数

Flask-SocketIO服务器使用轮询而不是WebSockets

我正在Flask-SocketIO服务器上工作正常。

但是,我的服务器日志中收到很多这样的请求:

"GET /socket.io/?EIO=3&transport=polling&t=LBS1TQt HTTP/1.1"

这是我正在使用的代码:

from flask import Flask, render_template, redirect, url_for
from flask_socketio import SocketIO, emit
import json

def load_config():
    # configuration
    return json.load(open('/etc/geekdj/config.json'))

config = load_config()

geekdj = Flask(__name__)

geekdj.config["DEBUG"] = config["debug"]
geekdj.config["SECRET_KEY"] = config["secret_key"]
geekdj.config.from_envvar("FLASKR_SETTINGS", silent=True)

socketio = SocketIO(geekdj)

@geekdj.route('/')
def index():
    return render_template('index.html')

# SocketIO functions

@socketio.on('connect')
def chat_connect():
    print ('connected')

@socketio.on('disconnect')
def chat_disconnect():
    print ("Client disconnected")

@socketio.on('broadcast')
def chat_broadcast(message):
    print ("test")
    emit("chat", {'data': message['data']})

if __name__ == "__main__":
    socketio.run(geekdj, port=8000)
Run Code Online (Sandbox Code Playgroud)

和JS中的index.html

<script …
Run Code Online (Sandbox Code Playgroud)

python websocket socket.io flask-socketio

4
推荐指数
2
解决办法
4303
查看次数

如何对Flask websocket服务器进行单元测试(Flask-SocketIO)

我想知道如何在我的烧瓶websocket服务器上进行单元测试.我的应用程序支持REST API(Flask-restful)和Web Socket(Flask-SocketIO)上的很多接口.所有websocket"发射"都在芹菜过程中进行.我有问题单元测试那些websocket逻辑.

  1. 几个人说,首先我必须分开这个rest-api + websocket应用程序.在单个服务器上运行整个应用程序(逻辑上)是否奇怪?

  2. 如何对websocket代码进行单元测试?

谢谢

python unit-testing websocket flask flask-socketio

4
推荐指数
1
解决办法
1656
查看次数

SocketIO 发送给特定用户(无需为每个客户端使用单独的空间)

我正在尝试开发一个支持后端长任务的网络应用程序。我在我的服务器上使用flask-socketio包和芹菜。我的工作流程如下:

  1. 当客户端打开 Html 页面时,我启动到服务器的套接字连接,该连接为用户创建一个 uid 并将其发回。
  2. 现在,一旦用户发布了对长任务的请求——我使用 celery 来安排它,一旦完成,我需要将其发送给发布请求的用户。(我在post请求中存储了相关的userid)

我查看了 @Miguels 对39423646/flask-socketio-emit-to-specific-user的回答,它为每个用户创建一个单独的房间,然后在该房间上广播消息。但我想问是否有其他更简单的方法来做到这一点,因为它似乎效率低下或强制的方式来做到这一点。

我还遇到了nodejs解决方案(how-to-send-a-message-to-a-preferred-client-with-socket-io),我觉得这是实现这一目标的更自然的方式。python-socketio 中也有类似的解决方案吗?


更新:经过更多搜索后,我在 github gist 上发现了以下解决方案。据此 -- ** flash-socketIO 已经将所有客户端放在request.sid** 指定的单独房间中。

我仍然希望讨论其他方法来做到这一点。具体来说,如果网站流量相当高,是否会导致房间过多?


更新(2)我当前的(工作)服务器代码使用 rooms这是从flask-SocketIO celery示例借用并修改的

@celery.task(bind=True)
def long_task(self, userid, url):
    # LONG TASK
    time.sleep(10)
    # meta = some result
    post(url, json=meta) 
    # It seems i can't directly emit from celery function so I mimic a post request and emit from that …
Run Code Online (Sandbox Code Playgroud)

python socket.io flask-socketio python-socketio

4
推荐指数
1
解决办法
2040
查看次数