Django通道redis通道层打开了很多连接

时间:2018-09-06 10:02:38

标签: django python-3.x python-asyncio django-channels

我们最近使用redis通道层后端将应用程序的一部分移植到了django通道。我们的部分设置仍在docker中的python2上运行,这就是为什么我们使用redis pub / sub将消息发送回客户端的原因。全局侦听器(inspired by this thread)捕获所有消息并将其分发到Django频道系统中。到目前为止,一切正常,但是我看到许多调试消息Creating tcp connection...通过。下面发布的输出对应于一个事件。侦听器和使用者似乎都在创建两个Redis连接。我对底层机制没有足够的知识,无法判断这是否是预期的行为,因此我在这里问。这是可以预期的吗?

侦听器使用全局通道层实例:

# maps the publish type to a method name of the django channel consumer
PUBLISH_TYPE_EVENT_MAP = {
    'state_change': 'update_client_state',
    'message': 'notify_client',
}
channel_layer = layers.get_channel_layer()


class Command(BaseCommand):
    help = u'Opens a connection to Redis and listens for messages, ' \
           u'and then whenever it gets one, sends the message onto a channel ' \
           u'in the Django channel system'

    ...

    def broadcast_message(self, msg_body):
        group_name = msg_body['subgrid_id'].replace(':', '_')
        try:
            event_name = PUBLISH_TYPE_EVENT_MAP[msg_body['publish_type']]
        # backwards compatibility
        except KeyError:
            event_name = PUBLISH_TYPE_EVENT_MAP[msg_body['type']]

        async_to_sync(channel_layer.group_send)(
            group_name, {
                "type": event_name,
                "kwargs": msg_body.get('kwargs'),
            })

使用者是JsonWebsocketConsumer,它是按以下方式初始化的

class SimulationConsumer(JsonWebsocketConsumer):

    def connect(self):
        """
        Establishes the connection with the websocket.
        """
        logger.debug('Incoming connection...')
        # subgrid_id can be set dynamically, see property subgrid_id
        self._subgrid_id = self.scope['url_route']['kwargs']['subgrid_id']
        async_to_sync(self.channel_layer.group_add)(
            self.group_name,
            self.channel_name
        )
        self.accept()

以及从侦听器调用的方法:

def update_client_state(self, event):
    """
    Public facing method that pushes the state of a simulation back
    to the client(s). Has to be called through django channels
    ```async_to_sync(channel_layer.group_send)...``` method
    """
    logger.debug('update_client_state event %s', event)
    current_state = self.redis_controller.fetch_state()
    data = {'sim_state': {
        'sender_sessid': self.session_id,
        'state_data': current_state}
    }
    self.send_json(content=data)

一个事件给了我这个输出

listener_1              | DEBUG !! data    {'publish_type': 'state_change', 'subgrid_id': 'subgrid:6d1624b07e1346d5907bbd72869c00e8'}
listener_1              | DEBUG !! event_name    update_client_state
listener_1              | DEBUG !! kwargs    None
listener_1              | DEBUG !! group_name    subgrid_6d1624b07e1346d5907bbd72869c00e8
listener_1              | DEBUG Using selector: EpollSelector
listener_1              | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
listener_1              | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
listener_1              | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
listener_1              | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
threedi-server_1        | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
threedi-server_1        | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)
threedi-server_1        | DEBUG update_client_state event {'type': 'update_client_state', 'kwargs': None}
threedi-server_1        | DEBUG Parsing Redis URI 'redis://:@redis-threedi-server:6379/13'
threedi-server_1        | DEBUG Creating tcp connection to ('redis-threedi-server', 6379)

0 个答案:

没有答案