python-3.x - 如何使用 aiohttp 在服务器端存储 websocket?
问题描述
我正在尝试使用 aiohttp 与房间进行简单的网络聊天。你能告诉我如何存储我的 websockets 连接吗?下面的一些代码被简化了一点。我一次又一次地从套接字收到 EOF 错误(我可以重现它),但我不知道为什么。所以,我有一个问题,我做对了吗?每次我重新加载或跟随链接时,我应该关闭 websockets 吗?如果没有,那么,我将如何将客户端与我已经打开的套接字连接?对不起我的英语^^谢谢。
应用程序.py
import asyncio
import aiohttp_jinja2
import jinja2
import hashlib
import collections
import os
from aiohttp_session import session_middleware
from aiohttp_session.cookie_storage import EncryptedCookieStorage
from aiohttp import web
from routes import routes
from middlewares import authorize
from motor import motor_asyncio as ma
from settings import *
basedir = os.path.dirname(os.path.realpath(__file__))
photo_dir = os.path.join(basedir, 'static/photo/')
async def on_shutdown(app):
for ws in app['websockets']:
await ws.close(code=1001, mesage='Server shutdown')
middle = [
session_middleware(EncryptedCookieStorage(hashlib.sha256(bytes(SECRET_KEY, 'utf-8')).digest())),
authorize
]
app = web.Application(middlewares=middle)
aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader('templates'))
for route in routes:
app.router.add_route(*route[:3], name=route[3])
app['static_root_url'] = '/static'
app.router.add_static('/static', 'static', name='static')
app.client = ma.AsyncIOMotorClient(MONGO_HOST)
app.db = app.client[MONGO_DB_NAME]
app.on_cleanup.append(on_shutdown)
app['websockets'] = collections.defaultdict(list)
app['online'] = {}
app['photo_dir'] = photo_dir
web.run_app(app)
和 websocket 处理程序
class CompanyWebSocket(web.View):
async def get(self):
ws = web.WebSocketResponse()
await ws.prepare(self.request)
session = await get_session(self.request)
self_id = session.get('user')
login = session.get('login')
company_id = self.request.rel_url.query.get('company_id')
message = Message(self.request.app.db)
company = Company(self.request.app.db)
my_companys = await company.get_company_by_user(self_id)
for c in my_companys:
self.request.app['websockets'][str(c['_id'])].append(ws)
async for msg in ws:
if msg.type == WSMsgType.TEXT:
if msg.data == 'close':
await ws.close()
else:
await message.save_for_company({'data': 'data'})
mess = {
'data': 'data'
}
# send mess to users in company
for company_ws in self.request.app['websockets'][company_id]:
await company_ws.send_json(mess)
elif msg.type == WSMsgType.ERROR:
log.debug('ws connection closed with exception %s' % ws.exception())
try:
self.request.app['websockets'][company_id].remove(ws)
except:
pass
for _ws in self.request.app['websockets'][company_id]:
await _ws.send_json({'user': login, 'type': 'left'})
return ws
解决方案
推荐阅读
- amazon-web-services - AWS、Elasticsearch、Filebeat:将索引策略应用于索引模式而不是特定索引
- windows - 哪些是预装的 PowerShell 模块以及为什么机器中可能缺少 cmdlet?
- php - 使用 php 7.1 在 Ubuntu 14.04.2 LTS 上安装 php-imap
- php - 在 Google Cloud Storage Bucket 中运行 PHP
- android - ConnectivityManager 只能检测连接性,但不能检测网络可用性
- ios - 如何以最快的方式检查我的 nsarray 是否包含另一个 nsarray 元素 IOS
- python - 绘制歌曲中每个独特声音循环的时间范围,使用 python Librosa 按声音相似度对行进行排序
- .net - web.config .net 中的#{variable name} 是什么
- python - AttributeError: 'list' 对象没有属性 'lower' - Sklearn
- r - 满足零比率条件的 R 个子集列