首页 > 解决方案 > 如何使用 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

标签: python-3.xwebsocketaiohttp

解决方案


推荐阅读