raise RuntimeError('你需要使用 eventlet 服务器。'

Posted

技术标签:

【中文标题】raise RuntimeError(\'你需要使用 eventlet 服务器。\'【英文标题】:raise RuntimeError('You need to use the eventlet server. 'raise RuntimeError('你需要使用 eventlet 服务器。' 【发布时间】:2018-08-02 04:18:50 【问题描述】:

在我的项目中,我创建了一个app

website_chat/views.py 代码:

async_mode = 'eventlet'

import os

from django.http import HttpResponse
import socketio

basedir = os.path.dirname(os.path.realpath(__file__))
sio = socketio.Server(async_mode=async_mode)
thread = None

website_chat/management/commands/runserver.py:

from django.core.management.commands.runserver import Command as RunCommand

from xxx/website_chat.views import sio


class Command(RunCommand):
    help = 'Run the Socket.IO server'

    def handle(self, *args, **options):
        if sio.async_mode == 'threading':
            super(Command, self).handle(*args, **options)
        elif sio.async_mode == 'eventlet':
            # deploy with eventlet
            import eventlet
            import eventlet.wsgi
            from Qyun.wsgi import application
            eventlet.wsgi.server(eventlet.listen(('', 8002)), application)
        elif sio.async_mode == 'gevent':
            # deploy with gevent
            from gevent import pywsgi
            from Qyun.wsgi import application
            try:
                from geventwebsocket.handler import WebSocketHandler
                websocket = True
            except ImportError:
                websocket = False
            if websocket:
                pywsgi.WSGIServer(
                    ('', 8000), application,
                    handler_class=WebSocketHandler).serve_forever()
            else:
                pywsgi.WSGIServer(('', 8000), application).serve_forever()
        elif sio.async_mode == 'gevent_uwsgi':
            print('Start the application through the uwsgi server. Example:')
            print('uwsgi --http :5000 --gevent 1000 --http-websockets '
                  '--master --wsgi-file django_example/wsgi.py --callable '
                  'application')
        else:
            print('Unknown async_mode: ' + sio.async_mode)

在我的wsgi.py:

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Qiyun02.settings")

from socketio import Middleware
from website_chat.views import sio
django_app = get_wsgi_application()
application = Middleware(sio, django_app)

但是当我运行服务器时,我收到以下错误:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
    return self.application(environ, start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/engineio/middleware.py", line 47, in __call__
    return self.engineio_app.handle_request(environ, start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/socketio/server.py", line 360, in handle_request
    return self.eio.handle_request(environ, start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/engineio/server.py", line 274, in handle_request
    environ, start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/engineio/socket.py", line 91, in handle_get_request
    start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/engineio/socket.py", line 133, in _upgrade_websocket
    return ws(environ, start_response)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/engineio/async_eventlet.py", line 15, in __call__
    raise RuntimeError('You need to use the eventlet server. '
RuntimeError: You need to use the eventlet server. See the Deployment section of the documentation for more information.

但是在website_chat/views.py,我已经配置了:

async_mode = 'eventlet'
sio = socketio.Server(async_mode=async_mode)

为什么我仍然收到此错误?

文件在那里:https://github.com/miguelgrinberg/python-socketio/blob/master/docs/index.rst#eventlet

【问题讨论】:

【参考方案1】:

如果您尝试将应用程序运行到我们这样的 uwsgi 环境中时发生此错误:

uwsgi -w myfile:app\
  --http11-socket 127.0.0.1:3333\
  --enable-threads\
  --threads 4\
  --logformat '%(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"'

其中myfile.py 包含应用程序:

import socketio
import eventlet
from engineio.async_drivers import gevent
from flask import Flask

sio = socketio.Server(async_mode="gevent_uwsgi", cors_allowed_origins='*', engineio_logger=True)
app = Flask(__name__)

# this generates the uwsgi-runnable application

my_wsgi = socketio.WSGIApp(sio)
app = socketio.Middleware(sio, my_wsgi)

如果您在安装 gevent 时遇到错误

pip3 install gevent

pip 可能会尝试安装一些最新的 gevent 版本:

21.1.0, 21.1.1, 21.1.2

这可能会导致安装错误,具体取决于您使用的操作系统(darwin 的一些问题)。 为了克服这些错误,它还可以使用 simpler,旧版本的 gevent:

pip3 install gevent==1.5.0

【讨论】:

【参考方案2】:

最后,我没有按照python-socketio的例子,我像下面这样配置wsgi.py

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Qyun.settings")

from socketio import Middleware
from website_chat.views import sio
django_app = get_wsgi_application()
application = Middleware(sio, django_app)

#
import eventlet
import eventlet.wsgi
eventlet.wsgi.server(eventlet.listen(('', 8000)), application)

它现在适用于这个问题。端口还是8000management/commands/runserver.py现在也可以删除了。

【讨论】:

看起来比以前的runserver简单易懂。 它正在工作,但静态文件丢失无法加载我已经尝试过 --insecure 但仍然无法正常工作

以上是关于raise RuntimeError('你需要使用 eventlet 服务器。'的主要内容,如果未能解决你的问题,请参考以下文章

jupyter 报错 raise RuntimeError(‘This event loop is already running‘)

jupyter 报错 raise RuntimeError(‘This event loop is already running‘)

python3.7.3使用web.py报错解决办法 and RuntimeError: generator raised StopIteration

完美解决windows系统raise RuntimeError(“Distributed package doesn‘t have NCCL “

Python3中raise用法

python raise