消息发布订阅图
在app中新建一个文件夹,然后新建base、server、client三个py文件。 base文件中:
import redis
class RedisSubPub(object):
def __init__(self, host='localhost', port=6379, db=13, password='',
pub='cong', sub='cong'):
pool = redis.ConnectionPool(host=host, port=port, db=db, password=password)
self.__conn = redis.StrictRedis(connection_pool=pool)
self.sub = sub
self.pub = pub
self.__sub = None
def public(self, msg):
if self.pub:
self.__conn.publish(self.pub, msg)
return True
else:
return False
def subscribe(self):
if self.sub:
self._sub = self.__conn.pubsub()
self._sub.subscribe(self.sub)
self._sub.parse_response()
return self._sub
接下来client:
'''
客户端只接收,不发布
客户端与服务端建立一个长链接,服务端订阅到消息之后,会发给客户端,由客户端显示出来
'''
import socket
def work():
client = socket.socket()
client.connect(('localhost', 8888))
while 1:
msg = client.recv(1024)
print(msg)
client.close()
if __name__ == '__main__':
work()
server:
import socketserver
from .base import RedisSubPub
obj = RedisSubPub()
class Server(socketserver.BaseRequestHandler):
def handle(self):
try:
__msg = obj.subscribe()
while 1:
msg = __msg.parse_response()
if msg:
self.request.sendall(msg[2])
except Exception as e:
print(self.client_address, 'close')
def setup(self):
print('before handle, connection {}'.format(self.client_address))
def finish(self):
print('finish run after handle')
if __name__ == '__main__':
host, port = 'localhost', 8888
server = socketserver.TCPServer((host, port), Server)
server.serve_forever()
然后进入到app/pubsub 启动一下:python server.py 我这里出现了一个错误:ImportError: attempted relative import with no known parent package 就是因为在导入RedisSubPub的时候,用的相对路径,把base前面的 . 去掉好了。 输入完没有报错就OK。
然后再打开一个cmd,进入pubsub目录,启动一下client:python client.py client连接上后,server端出现了消息
然后,再打开一个cmd,进入pubsub目录,然后进入ipython。
from base import RedisSubPub
In [2]: obj = RedisSubPub()
In [3]: obj.public('这是一条消息订阅')
Out[3]: True
In [4]:
理论上,订阅消息发布,然后传给server,server再给client。 可以看到client已经接收到了,是比特类型的。 已经decode了依旧不行。
当server收到了我们发布的信息之后,就会长链接给我们的客户端。
|