Python SocketIo与Django的集成
我一直在尝试将socketio与Django集成在一起,我得到了以下错误Python SocketIo与Django的集成,python,node.js,django,socket.io,Python,Node.js,Django,Socket.io,我一直在尝试将socketio与Django集成在一起,我得到了以下错误 [31/Mar/2020 14:50:27] "GET /socket.io/?EIO=3&transport=polling&t=N4n4ds4&b64=1 HTTP/1.1" 200 117 [31/Mar/2020 14:50:27] "POST /socket.io/?EIO=3&transport=polling&t=N4n4dsj&b64=1&sid=90
[31/Mar/2020 14:50:27] "GET /socket.io/?EIO=3&transport=polling&t=N4n4ds4&b64=1 HTTP/1.1" 200 117
[31/Mar/2020 14:50:27] "POST /socket.io/?EIO=3&transport=polling&t=N4n4dsj&b64=1&sid=9053be92266c46148304c09833b2ebe8 HTTP/1.1" 200 2
Traceback (most recent call last):
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 137, in run
self.result = application(self.environ, self.start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__
return self.application(environ, start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/engineio/middleware.py", line 60, in __call__
return self.engineio_app.handle_request(environ, start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/socketio/server.py", line 558, in handle_request
return self.eio.handle_request(environ, start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/engineio/server.py", line 377, in handle_request
environ, start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/engineio/socket.py", line 108, in handle_get_request
start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/engineio/socket.py", line 152, in _upgrade_websocket
return ws(environ, start_response)
File "/Users/murali/yourenv/lib/python3.7/site-packages/engineio/async_drivers/eventlet.py", line 16, 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.
[31/Mar/2020 14:50:27] "GET /socket.io/?EIO=3&transport=websocket&sid=9053be92266c46148304c09833b2ebe8 HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 52220)
Traceback (most recent call last):
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 650, in process_request_thread
self.finish_request(request, client_address)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 720, in __init__
self.handle()
File "/Users/murali/yourenv/lib/python3.7/site-packages/django/core/servers/basehttp.py", line 174, in handle
self.handle_one_request()
File "/Users/murali/yourenv/lib/python3.7/site-packages/django/core/servers/basehttp.py", line 182, in handle_one_request
self.raw_requestline = self.rfile.readline(65537)
File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 589, in readinto
return self._sock.recv_into(b)
ConnectionResetError: [Errno 54] Connection reset by peer
----------------------------------------
我所指的链接
下面是我的代码:
requirements.txt:
enum-compat==0.0.2
eventlet==0.25.1
python-engineio
python-socketio
pytz==2018.7
six==1.10.0
settings.py:在已安装的应用程序中添加了socketio:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'socketio'
]
wsgi.py:
import os
import eventlet
import socketio
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'integrate_socketio.settings')
application = get_wsgi_application()
sio = socketio.Server()
application = socketio.WSGIApp(sio, application)
url.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
#path('admin/', admin.site.urls),
path('', views.hello, name='hello')
]
view.py
import eventlet
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='eventlet')\
@sio.on('connection-bind')
def connection_bind(sid, data):
print("sid:",sid,"data",data)
@sio.on('message')
def message(data):
print(data)
sio.emit('test',data)
@sio.on('disconnect')
def test_disconnect(sid):
print("Disconnected")
def hello(data):
return HttpResponse("Hello")
下面是用nodejs编写的客户端代码
var io = require('socket.io-client');
var socket = io.connect('http://localhost:8000', {reconnect: false});
socket.on('connect', function (socket) {
console.log('Connected!');
});
socket.emit('message', 'messgae', 'test msg');
socket.on('test', function (data) {
console.log(data);
})
要运行:
python manage.py runserver
当我在浏览器中打开时会得到响应,但当我运行nodejs客户端时会出现上述错误
任何帮助都将不胜感激:)
提前谢谢 问题
问题在于socketio.Server
实例(即sio
)的async\u mode
参数。该参数基本上选择运行时使用的模型。每个模型类型都需要以特定的方式运行。async\u模式的默认值为'eventlet'
,这意味着SocketIO服务器需要与eventlet一起运行。在您的情况下,它似乎默认为'eventlet'
,但您没有使用eventlet运行django服务器,这会引发错误。要解决此问题,您可以更改sio
参数以与您的方式兼容(解决方案1),也可以将wsgi.py配置为使用eventlet运行服务器(解决方案2)
解决方案1
您可以在初始化时更改sio
参数,如下所示:
sio=socketio.Server(async_mode='mode')#将'mode'更改为您的模式
您可以根据运行服务器的方式更改“模式”
。选项有'gevent\u uwsgi'
,'gevent'
,或'threading'
(或'eventlet'
,无,但两者都不能解决您的问题)
从run语句的外观来看,您没有使用gunicorn或uwsgi,因此在您的情况下,最好使用threading
或gevent
。(底部引用的官方文件中分别有使用gunicorn或uwsgi与'gevent'
或'gevent\u uwsgi'
的说明)
如果您使用的是'threading'
,则不需要在wsgi.py中安装或更改任何内容(模式除外),但它的性能相对较慢
如果您使用的是'gevent'
,则需要按如下方式安装gevent:
$pip安装gevent
然后,您需要更改wsgi.py中的一些设置。如果已安装gevent websocket传输,请将以下内容添加到wsgi.py的底部:
从gevent导入pywsgi
从geventwebsocket.handler导入WebSocketHandler
pywsgi.WSGIServer(“”,8000),应用程序,
handler\u class=WebSocketHandler).永远服务\u()
如果不是,则添加以下内容:
从gevent导入pywsgi
pywsgi.WSGIServer(“”,8000),app.serve_forever()
解决方案2
如果决定将wsgi.py配置为与eventlet一起运行,则首先安装eventlet
$pip安装eventlet
…并将以下内容添加到wsgi.py的底部:
导入eventlet
导入eventlet.wsgi
eventlet.wsgi.server(eventlet.listen(“”,8000)),应用程序)
引用
我得到了所有的信息。官方文档中也有使用“解决方案1”中其他模式的说明