首先聲明葱蝗,這么干純粹是為了好玩喳资。
通常我們用Redis主要是為了存儲(chǔ)一些數(shù)據(jù),由于數(shù)據(jù)在內(nèi)存里轰异,所以查詢(xún)更新很快。同時(shí)我們也可以利用 Pub/Sub 功能來(lái)實(shí)現(xiàn)消息發(fā)布/訂閱暑始。但是今天我們來(lái)說(shuō)說(shuō)怎么通過(guò)Redis的list來(lái)實(shí)現(xiàn) Server - Client 的同步通信搭独。
具體需求
Client 端運(yùn)行后監(jiān)聽(tīng) Server 端派發(fā)的請(qǐng)求,然后執(zhí)行一些操作蒋荚,并將結(jié)果返回給 Server 端戳稽。
實(shí)現(xiàn)想法
- 利用 Redis 的 list 數(shù)據(jù)結(jié)構(gòu)馆蠕,使用阻塞 pop 的方式實(shí)現(xiàn) Client 端等待派發(fā)命令和 Server 端等待返回結(jié)果期升。
- 首先Server端生成一個(gè)全局唯一的key,并將key和data一起push到我們指定的一個(gè)隊(duì)列里互躬,這里是“myqueue”播赁。lpush之后,Server端就使用brpop等待從“key”隊(duì)列返回結(jié)果吼渡,并設(shè)置超時(shí)時(shí)間為2秒容为。
- Client端啟動(dòng)后,使用brpop從指定的隊(duì)列里獲取派發(fā)的命令寺酪,一旦收到Server端派發(fā)的數(shù)據(jù)坎背,Client就會(huì)獲取key和data,然后做自己的一些處理寄雀,處理完成后得滤,就往“key”隊(duì)列里lpush執(zhí)行結(jié)果。
- 最后盒犹,Server端會(huì)從“key”隊(duì)列里使用brpop獲取執(zhí)行結(jié)果懂更。
實(shí)現(xiàn)代碼
import redis
import time
import json
import threading
host = 'localhost'
port = 6322
queue = 'myqueue'
class Server(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
pool = redis.BlockingConnectionPool(host=host, port=port, db='0')
conn = redis.Redis(connection_pool=pool)
idx = 0
while True:
idx = idx + 1
key = str(idx)
data = "request_" + key
request = {'id': key, 'data': data}
print 'Server: Send request: %s' % request
conn.lpush(queue, json.dumps(request))
response = conn.brpop(key, 2)
if response:
print 'Server: Receive response: %s' % response[1]
else:
print "Server: Timeout!!!"
time.sleep(1)
class Client(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
pool = redis.BlockingConnectionPool(host=host, port=port, db='0')
conn = redis.Redis(connection_pool=pool)
while True:
msg = conn.brpop(queue)[1]
print 'Client: Receive request: %s' % msg
time.sleep(0.1)
d = json.loads(msg)
key = d.get('id')
d['data'] = "response_" + key
print 'Client: Send response: %s' % d
conn.lpush(key, json.dumps(d))
conn.expire(key, 5)
server = Server()
server.start()
client = Client()
client.start()