Отправка множества запросов в одно соединение через веб-сокет без повторного подключения - PullRequest
0 голосов

Моя программа на python работает так медленно, потому что заставляет сокет переподключаться для любого запроса.Я хочу сделать одно соединение и отправить запрос, без повторного соединения

Мои функции в файле send_by_socket.py, некоторые другие функции и вызов класса send_to_socket для отправки журнала сообщений.Сейчас это работает, но очень медленно.Причина - установить новое соединение для любого сообщения.Я хочу одно соединение или опрос для использования без повторного подключения.Как это сделать, возможно, есть хороший пример с исходным кодом?

import asyncio
import websockets
from logging import StreamHandler
import json


async def async_send(message):
    async with websockets.connect('wss://****.com/chat') as web_socket:
        await web_socket.send(message)


class WebSocketHandler(StreamHandler):
    def __init__(self):
        StreamHandler.__init__(self)

    def emit(self, record):

        msg = json.dumps({'log': {'message': record.message, 'date': record.asctime, 'level': record.levelname}})
        try:
            asyncio.get_event_loop().run_until_complete(async_send(msg))
        except ConnectionRefusedError:
            pass


def send_to_socket(msg_dict):
    msg = json.dumps(msg_dict)
    try:
        asyncio.get_event_loop().run_until_complete(async_send(msg))
    except ConnectionRefusedError:
        pass

Теперь программа тратит около 1 - 1,2 сек на запрос.Я пытаюсь

con = websockets.connect('wss://****.com/chat')
con.send('some thing')

, но имею ошибку AttributeError: у объекта 'Connect' нет атрибута 'send'

1 Ответ

1 голос
python
import asyncio
import websockets
from logging import StreamHandler
import json
import time


def singleton(cls):
    instances = {}

    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance


@singleton
class SendToWebSocket:
    """
    Send message in  web-socket, use one connection for sending.
    Try make new connection, if  old is lost.
    """
    __ws = None
    __url = "wss://***.com/chat"

    def __init__(self):
        self.retryTime = 0
        self.retryRepeat = 30
        self.__create_connect()

    @asyncio.coroutine
    def __create_connect(self):
        if (time.time() - self.retryTime) > self.retryRepeat:
            try:
                self.__ws = yield from websockets.connect(self.__url)
                self.retryTime = 0
            except ConnectionRefusedError:
                self.retryTime = time.time()

    def send(self, message):
        t = type(message)
        if t is dict:
            msg = json.dumps(message)
        elif t is str:
            msg = message
        else:
            raise ValueError("Message must be str or dict. Received %s" % type(t))
        if self.__ws is not None:
            try:
                asyncio.get_event_loop().run_until_complete(self.__async_send(msg))
                # print('Send normal')
            except ConnectionRefusedError:
                # print("Can't send")
                # try recreate connect
                self.__create_connect()
        else:
            asyncio.get_event_loop().run_until_complete(self.__create_connect())

    async def __async_send(self, message):
        await self.__ws.send(message)


class WebSocketHandler(StreamHandler):
    """Custom handler for logging library"""

    def __init__(self):
        StreamHandler.__init__(self)
        self.web_socket = SendToWebSocket()

    def emit(self, record):

        msg = json.dumps({'log': {'message': record.message, 'date': record.asctime, 'level': record.levelname}})
        try:
            self.web_socket.send(msg)
        except ConnectionRefusedError:
            pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...