使用unix socket的django-websocket-redis redis连接

时间:2017-01-17 19:52:55

标签: python django websocket redis

我正在使用django-websocket-redis并在我的settings.py中有这个:

WS4REDIS_CONNECTION = {
    'host': 'unix://var/run/redis/redis.sock',
    'db': 0,
    # 'port': 16379,
    # 'password': 'verysecret',
}

我尝试了所有可能的'主机'参数并且无法使用unix socket代替tcp进行连接。我总是得到这样的信息:

ConnectionError: Error -2 connecting to /var/run/redis/redis.sock:6379. Name or service not known.

有没有办法使用unix socket将ws4redis从django连接到redis?如果有,怎么样?

1 个答案:

答案 0 :(得分:1)

TL; DR:您必须覆盖ws4redis的默认Redis连接设置

当我实现自定义Django命令时,我已经碰到了这一点,该命令应该在某些服务器端事件上发送websocket消息。

如果您查看RedisPublisher课程的源代码,您会注意到最上面的这一行:

redis_connection_pool = ConnectionPool(**settings.WS4REDIS_CONNECTION)

ConnectionPool.__init__()状态的评论如下:

  

默认情况下,创建TCP连接指定了connection_class。   使用redis.UnixDomainSocketConnection作为unix套接字。

因此,当您实例化RedisPublisher时,它使用ConnectionPool,默认情况下,它不知道有关套接字的任何信息。因此,有两种方法可以:

  1. Connection实例化中将默认UnixDomainSocketConnection切换为ConnectionPool
  2. ConnectionPool连接替换具有内置功能的StrictRedis来使用unix socket(命名参数unix_socket_path)。
  3. 这是我使用第二种方法解决它的方式(对我来说看起来更干净):

    from redis import StrictRedis
    from django.conf import settings
    from ws4redis.publisher import RedisPublisher
    from ws4redis.redis_store import RedisMessage
    
    r = StrictRedis(**settings.WS4REDIS_CONNECTION)
    publisher = RedisPublisher(facility='foobar', broadcast=True)
    publisher._connection = r
    msg = RedisMessage('ping')
    publisher.publish_message(msg)
    

    整个魔法在publisher._connection行,最终切换RedisPublisher类使用的连接。 由于_connection假设受保护访问,这看起来有点脏,但是工作解决方案。

    您还需要指定以下WS4REDIS_CONNECTION设置:

    WS4REDIS_CONNECTION = {
        'unix_socket_path': '/tmp/redis.sock'
    }
    

    这是wsgi所必需的,因为它似乎使用内置的redis.py功能连接到unix套接字,如docs中所述