Reputation: 101
I'm using django-websocket-redis and have this in my settings.py:
WS4REDIS_CONNECTION = {
'host': 'unix://var/run/redis/redis.sock',
'db': 0,
# 'port': 16379,
# 'password': 'verysecret',
}
I tried all possible combinations of 'host' parameter and can't get it to connect using unix socket instead of tcp. I always get this message:
ConnectionError: Error -2 connecting to /var/run/redis/redis.sock:6379. Name or service not known.
Is there a way to connect ws4redis from django to redis using unix socket? If there is, how?
Upvotes: 1
Views: 802
Reputation: 655
TL;DR: you have to override default Redis connection settings of ws4redis
I've bumped into this when I was implementing custom Django command, which was supposed to send a websocket message on certain server-side events.
If you look at the source code of RedisPublisher
class, you will notice this line at the very top:
redis_connection_pool = ConnectionPool(**settings.WS4REDIS_CONNECTION)
while comments for ConnectionPool.__init__()
state following:
By default, TCP connections are created connection_class is specified. Use
redis.UnixDomainSocketConnection
for unix sockets.
So when you're instantiating RedisPublisher
it uses ConnectionPool
which, by default, does not know anything about sockets. Therefore 2 approaches are possible:
Connection
to UnixDomainSocketConnection
in ConnectionPool
instantiation or ConnectionPool
with StrictRedis
connection which has built-in capabilities to use unix socket (named argument unix_socket_path
). This is how I solved it using 2nd approach (it appears cleaner for me):
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)
The whole magic is in publisher._connection
line which ultimately switches connection, used by RedisPublisher
class.
Since _connection
assumes protected access, this looks like a bit dirty, but working solution.
You also need to specify following WS4REDIS_CONNECTION
settings:
WS4REDIS_CONNECTION = {
'unix_socket_path': '/tmp/redis.sock'
}
This is required for wsgi, since it appears to use built-in redis.py
capability to connect to unix socket as it stated in docs
Upvotes: 1