Как хранить веб-сокеты на стороне сервера с помощью aiohttp? - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь сделать простой веб-чат с комнатами, используя aiohttp. Можете ли вы посоветовать мне, как хранить мои соединения через веб-сокеты? Некоторый код ниже немного упрощен. Я получаю ошибку EOF от сокета время от времени (и я могу воспроизвести это), но я не знаю почему. Итак, у меня есть вопрос, я делаю это правильно? Должен ли я закрывать веб-сокеты каждый раз, когда перезагружаюсь или следую по ссылке? Если нет, то как я подключу клиента с уже открытым сокетом? Извините за мой англ ^^ спасибо.

app.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

...