在一个websocket连接中发送许多请求而无需重新连接

时间:2019-05-31 14:38:35

标签: python-3.x websocket

我的python程序工作如此缓慢,因为对于任何请求都可以重新建立套接字。我想建立一个连接并发送请求,而无需重新连接

我在文件send_by_socket.py中的函数,其他一些函数和类调用send_to_socket用于发送日志消息。现在可以正常工作,但是非常慢。原因-为任何消息建立新的连接。我想要单连接或轮询以使用它而无需重新连接。如何做到,possibel在源代码方面有很好的例子?

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:“连接”对象没有属性“发送”

1 个答案:

答案 0 :(得分: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