zoukankan      html  css  js  c++  java
  • redis的发布订阅模式pubsub

    前言

    redis支持发布订阅模式,在这个实现中,发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端),而是将信息发送给频道(channel),然后由频道将信息转发给所有对这个频道感兴趣的订阅者。

    发送者无须知道任何关于订阅者的信息,而订阅者也无须知道是那个客户端给它发送信息,它只要关注自己感兴趣的频道即可。

    对发布者和订阅者进行解构(decoupling),可以极大地提高系统的扩展性(scalability),并得到一个更动态的网络拓扑(network topology)。

    redis 发布订阅主要由三个entity组成:channel/subscriber/publisher。

    channel:

    频道有两种类型

    明确型,news.sport,体育类新闻

    模糊型,news.*,各种新闻

    下面实现对于这两种是透明的。

    # -*- coding:utf-8 -*-
    
    
    class Channel(object):
    
        def __init__(self, channel=''):
            self.channel = channel
    
        def __str__(self):
            return self.channel
    
    
    class ChannelFactory(object):
    
        def __init__(self, *channels):
            if isinstance(channels[0], (tuple, list)):
                self.channel_list = [Channel(channel) for channel in channels[0]]
            self.channel_list = [Channel(channel) for channel in channels]
    
        def get_channels(self):
            return self.channel_list

    user:

    主要有两类,订阅者subscriber和发布者publisher,他们都继承自Pubsub,由继承关系实现:

    # -*- coding:utf-8 -*-
    import redis
    
    
    class Pubsub(object):
    
        def __init__(self, redis_config):
            pool = redis.ConnectionPool(
                    host=redis_config.get('host'),
                    port=redis_config.get('port'),
                    db=redis_config.get('db')
            )
            self.redis = redis.StrictRedis(connection_pool=pool)
    class Subscriber(Pubsub): def __init__(self, redis_config): Pubsub.__init__(self, redis_config=redis_config) self.pubsub = self.redis.pubsub() def subscribe(self, *channel): self.pubsub.subscribe(*channel) def psubscribe(self, *channel_pattern): self.pubsub.psubscribe(*channel_pattern) def listen(self): for item in self.pubsub.listen(): yield item def unsubscribe(self, *channel): self.pubsub.unsubscribe(*channel) def punsubscribe(self, *channel_pattern): self.pubsub.unsubscribe(*channel_pattern) class Publisher(Pubsub): def __init__(self, redis_config): Pubsub.__init__(self, redis_config=redis_config) def publish(self, channel, message): self.redis.publish(channel, message)

    测试

    分两部分,订阅进程和发布进程

    订阅进程:

    from config import redis as redis_config
    from subscriber import Subscriber
    from channel import ChannelFactory
    
    if __name__ == '__main__':
        channel = ChannelFactory('news.*', 'movie.*').get_channels()
        sub = Subscriber(redis_config)
        sub.psubscribe(channel)
        for item in sub.listen():
            print item

    发布进程:

    from config import redis as redis_config
    from publisher import Publisher
    from channel import Channel
    
    if __name__ == '__main__':
        channel = Channel('news.abc')
        pub = Publisher(redis_config)
        pub.publish(channel, 'aaaaaaaa')
  • 相关阅读:
    精通javascript、javascript语言精粹读书笔记
    javascript语言精粹。3、对象;4、函数;深入原型链,对象的原理!
    权限管理
    javascript碎碎念(面向对象备忘)
    几个JavaScript面试题
    JavaScript类属性的定义方法和区别
    j
    Java调用SQL存储过程 输入输出参数(转)
    Java中文乱码解决
    js中eval详解
  • 原文地址:https://www.cnblogs.com/kangoroo/p/6722614.html
Copyright © 2011-2022 走看看