当我使用python-socketio和gunicorn在python环境中开发一些socket.io服务时,我在这里遇到了一个问题。
我使用的是 Mac OS X,我使用的是 python 3.7。
环境设置
$ pip install python-socketio
$ pip install gunicorn
服务器端代码
app.py
import socketio
sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files = {
'/': './socketio-client.html'
})
@sio.event
def connect(sid, environ):
print(sid, 'connected')
@sio.event
def disconnect(sid):
print(sid, 'disconnected')
Run Code Online (Sandbox Code Playgroud)
客户端代码
socketio-client.html
<html>
<head>
<title>Socket.IO Demo</title>
<script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>
</head>
<body>
<h1>Socket.IO Demo</h1>
<script>
const sio = io();
sio.on('connect', () => {
console.log('connected');
});
sio.on('disconnect', () => {
console.log('disconnected');
});
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
启动程序
我将文件放在同一文件夹中。并按照命令启动它。
$ …
我想要连接websockets,但启动时出现错误。
uvicorn app:app --reload --ws websockets
要求
操作系统:Linux Ubuntu 20.04 LTS
Python 3.8.6
浏览器:Chrome 88.0.4324.182
快速API ==0.63.0
python-engineio ==4.0.0
python-socketio ==5.0.4
星星==0.13.6
独角兽==0.13.3
网络套接字==8.1
应用程序.py
from typing import Optional
import socketio
from fastapi import FastAPI, Query, WebSocket
sio = socketio.AsyncServer(
async_mode="asgi", cors_allowed_origins="*", logger=True, engineio_logger=True
)
app = FastAPI(debug=True)
app_socketio = socketio.ASGIApp(sio)
app.mount(path="/", app=app_socketio)
@app.websocket("/items/{item_id}/ws")
async def websocket_endpoint(
websocket: WebSocket,
item_id: str,
q: Optional[int] = None,
):
# pylint: disable=C0103,W0613
await websocket.accept()
while True: …Run Code Online (Sandbox Code Playgroud) 在一个运行在 RaspberryPi 上、大约有 10-20 个客户端的小型 Flask Web 服务器上,我们会定期收到此错误:
Error on request:
Traceback (most recent call last):
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/werkzeug/serving.py", line 270, in run_wsgi
execute(self.server.app)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/werkzeug/serving.py", line 258, in execute
application_iter = app(environ, start_response)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/flask_socketio/__init__.py", line 43, in __call__
start_response)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/engineio/middleware.py", line 47, in __call__
return self.engineio_app.handle_request(environ, start_response)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/socketio/server.py", line 360, in handle_request
return self.eio.handle_request(environ, start_response)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/engineio/server.py", line 291, in handle_request
socket = self._get_socket(sid)
File "/home/pi/3D_printer_control/env/lib/python3.7/site-packages/engineio/server.py", line 427, …Run Code Online (Sandbox Code Playgroud) socketio 客户端成功连接到服务器并向emit服务器发送消息,但向客户端的另一个方向服务器失败。我找不到错误的根源。这是
这是基于python-socketioapp.py网站中的示例的服务器 python :
from aiohttp import web\nimport socketio\n\nsio = socketio.AsyncServer()\napp = web.Application()\nsio.attach(app)\n\nasync def index(request):\n """Serve the client-side application."""\n with open(\'index.html\') as f:\n return web.Response(text=f.read(), content_type=\'text/html\')\n\n@sio.on(\'connect\', namespace=\'/chat\')\ndef connect(sid, environ):\n print("connect", sid)\n\n@sio.on(\'chat message\', namespace=\'/chat\')\nasync def message(sid, data):\n print("server received message!", data)\n await sio.emit(\'reply\', data)\n await sio.send(data)\n\n@sio.on(\'disconnect\', namespace=\'/chat\')\ndef disconnect(sid):\n print(\'disconnect\', sid)\n\napp.router.add_static(\'/static\', \'static\')\napp.router.add_get(\'/\', index)\n\nif __name__ == \'__main__\':\n web.run_app(app)\nRun Code Online (Sandbox Code Playgroud)\n\n我尝试评论其中之一await sio.emit(\'reply\', data)或await sio.send(data)但结果是相同的。这是 javascript 客户端index.html:
<html>\n <head>\n <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>\n …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 websocket 连接两台服务器,但我需要多个 websocket 连接。因此,如果客户端与服务器 A 通信,则需要为此客户端与服务器 B 建立 Websocket 连接。如果另一个客户端连接,我需要从服务器 A 到服务器 B 的第二个 Websocket 连接。
这样的事情可能吗?我找不到任何关于此的文档。
两个服务器都是用 python 编写的。我正在使用 socketIO 库。
import socketio
sio = socketio.Client()
sio.connect('xxx.xxx.xxx.xxx')
Run Code Online (Sandbox Code Playgroud)
我需要将连接存储在列表中,然后如果客户端向服务器 B 请求某些内容,服务器 A 需要查找正确的连接并将请求发送到服务器 B。
原因是,服务器 B 为每个 WS 连接创建一个实例,并在连接关闭时销毁它。
有什么建议么?
我使用 Aiohttp 服务器和 python-socket-io 构建了一个聊天应用程序。当我尝试在 nginx 中托管此应用程序时,我在主管错误日志中发现了此错误(错误日志路径= /var/log/gunicorn/gunicorn.err.log )
[2022-05-27 04:16:31 +0000] [32957] [ERROR] Error handling request
/chatserver Traceback (most recent call last):
File "/home/ubuntu/env/lib/python3.8/site-packages/gunicorn/workers/sync.py", line 136, in handle
self.handle_request(listener, req, client, addr)
File "/home/ubuntu/env/lib/python3.8/site-packages/gunicorn/workers/sync.py", line 184, in handle_request
for item in respiter:
TypeError: 'coroutine' object is not iterable
Run Code Online (Sandbox Code Playgroud)
这是我的 aiohttp 服务器设置。
import socketio
from aiohttp import web
import aiohttp_cors
# create aiohttp application
app = web.Application()
# creates a new Async Socket IO Server
sio = socketio.AsyncServer(
cors_allowed_origins='*',
cors_credentials=True …Run Code Online (Sandbox Code Playgroud) 我正在尝试开发一个支持后端长任务的网络应用程序。我在我的服务器上使用flask-socketio包和芹菜。我的工作流程如下:
我查看了 @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) 据我了解,websocket是协议,socketio是实现该协议的库。
所以我决定从 python 转向,websocket-client因为python-socketio使用装饰器实现行为似乎更容易@sio.on('subject')。
我正在使用该connect方法的不同参数,但总是遇到错误。
使用sio.connect('ws://echo.websocket.org')或sio.connect('http://echo.websocket.org', transports=['websocket'])错误是:
Attempting polling connection to http://echo.websocket.org/socket.io/?transport=polling&EIO=3
Traceback (most recent call last):
File "/home/lucas/projects/python/py-websockets/client/test.py", line 6, in <module>
sio.connect('ws://echo.websocket.org')
File "/home/lucas/.virtualenvs/py-websockets/lib/python3.6/site-packages/socketio/client.py", line 210, in connect
six.raise_from(exceptions.ConnectionError(exc.args[0]), None)
File "<string>", line 3, in raise_from
socketio.exceptions.ConnectionError: Unexpected status code 404 in server response
Run Code Online (Sandbox Code Playgroud)
因此,查看我尝试过的日志sio.connect('http://echo.websocket.org', transports=['websocket'], socketio_path=''),但只打印日志Attempting WebSocket connection to ws://echo.websocket.org//?transport=websocket&EIO=3,然后它进入某种无限循环并且永远不会返回。
这是我正在尝试的代码:
import socketio
sio = socketio.Client(logger=True, engineio_logger=True) …Run Code Online (Sandbox Code Playgroud) 我正在开展一个班级项目,我们正在尝试捕获 socket.io 异常。具体来说,socketio.exceptions.ConnectionError:连接被服务器拒绝我们这样做的目的是在尚未建立连接的情况下继续尝试连接。
我们尝试查看https://python-socketio.readthedocs.io/en/latest/上的文档,但找不到任何内容。同样,如果尚未建立连接,我们将尝试连接到服务器。我们正在研究 socket.reconnect() 但这似乎只有在建立连接后才起作用。我们正在尝试在树莓派 3 上实现这一点。我们编写了一个脚本来在启动时执行客户端代码,但在执行脚本后将与 pi 建立以太网连接。
import socketio
import opc, time
import json
# Initiate socket client
socket = socketio.Client()
# Initiate socket client for fadecandy server (little chip between Led strip and Pi
fade_client = opc.Client('localhost:xxxx')
# Establish connection to server
socket.connect("website url", namespaces=['/pi'])
# stuff to do after connection, mainly change led lights through
# fadecandy server
Run Code Online (Sandbox Code Playgroud) 大家好,我有以下代码,但由于某种原因,我不断收到以下错误,但它似乎可以在同事的电脑上运行。我们似乎无法弄清楚为什么这对我的不起作用。
我们还仔细检查了我们是否使用 dir() 导入相同的 socketio
我尝试在 sio.connect 和 sio.emit 中指定名称空间,但仍然没有成功!
socketio.exceptions.BadNamespaceError: / is not a connected namespace.
bearerToken = 'REDACT'
core = 'REDACT'
output = 'REDACT'
import socketio
import json
def getListeners(token, coreUrl, outputId):
sio = socketio.Client(reconnection_attempts=5, request_timeout=5)
sio.connect(url=coreUrl, transports='websocket')
@sio.on('mwedge:batch:stats')
def batchStats(data):
if (outputId in data['outputStats']):
listeners = data['outputStats'][outputId][16]
print("Number of listeners ", len(listeners))
ips = []
for listener in listeners:
ips.append(listener[1])
print("Ips", ips)
def authCallback(data):
print(json.dumps(data))
sio.emit(event='auth',
data={
'token': token
},
callback=authCallback)
getListeners(bearerToken, core, output)
Run Code Online (Sandbox Code Playgroud) 我正在选择一个python库来编写嵌入在我的网站中的实时聊天功能页面。
我发现基于Socket.IO,两个图书馆python-socketio和gevent-socketio:
Socket.IO实时服务器的Python实现。
Socket.IO是类似于WebSocket的抽象,可实现浏览器和服务器之间的实时通信。gevent-socketio是该协议的Python实现。
您会看到,它们都是Socket.IO的实现。
我想选择其中之一(或者是否有比我不知道的更好的库)。
我的考虑要点是:
我的python后端项目是由Django / Django-Rest-Framework框架编写的。
我的项目很着急,我想使用更方便的lib,编写更少的代码来实现我的要求。
我上网冲浪,gevent-socketio实时聊天必须使用gevent python WSGI服务器,我不确定这是否限制了我的项目部署。
谁能给我建议为我选择最佳图书馆?
问题
使用 eventlet 0.25.0 和 python-socketio 4.0.3 w/ Python 3.7,我试图让两个 Python 脚本与 websocket 进行通信。服务器脚本运行良好:
import socketio # type: ignore
import eventlet
import json
import util as u # type: ignore
eventlet.monkey_patch()
WSGI_LOG_FORMAT = '%(client_ip)s "%(request_line)s" %(status_code)s %(body_length)s %(wall_seconds).6f'
class DatabaseServer:
""" Initializes a server using socketio and eventlet. Use start() and stop() to... start and stop it.
push() pushes new data to all clients
"""
def __init__(self):
self.server = socketio.Server(async_mode='eventlet', namespace='/socket.io')
self.server.on('connect', self.connect, namespace='/socket.io')
self.server.on('disconnect', self.disconnect, namespace='/socket.io')
self.server.on('client_response', self.client_response, namespace='/socket.io') …Run Code Online (Sandbox Code Playgroud) 我想我正在寻找一个全是 python socketio 模块。然后当我开始使用带有 socketio 的消息代理时,文档很好地展示了,使用 redis。但是,我觉得奇怪的是 python-socketio 客户端没有显示如何连接到消息代理。这是意图并将其留给项目的追随者吗?
我不得不仅仅依靠 python redis 来查看 python-socketio 如何连接到 redis,前提是它给了带有地址的 db。此外,我发现 socket.io 是这一切的默认频道,并发出比我预期更多的信息。
预期:{'foo':'bar'}
观察到:{'method': 'emit', 'event': 'event', 'data': {'foo': 'bar'}, 'namespace': '/learning_it', 'room': None, 'skip_sid ':无,'回调':无,'host_id':''}
从这个模块的使用来看,我们是不是可以随心所欲地操作呢?
谢谢来自粉丝的 Miguel Grinberg。
python-socketio ×13
python ×12
socket.io ×7
websocket ×4
python-3.x ×2
aiohttp ×1
coroutine ×1
fastapi ×1
flask ×1
gunicorn ×1
javascript ×1
reactjs ×1