使用redis订阅/发布创建简单聊天室

时间:2021-12-10 10:08:17

英汉对照,个人翻译,水平有限,供参考

来源页:http://programeveryday.com/post/create-a-simple-chat-room-with-redis-pubsub/

When it comes to NoSQL, I believe that Redis is the king thanks to its ease of use and diversity.

当redis支持NoSQL时,我相信redis因它的易用性和多样性而为王

I plan on doing a few posts on Redis this week, but I wanted to start off with something to show how easy it is to get started with it. That said, let's define what Redis is first. At it's bare minimum, it's a key value store. It allows persistent data but also works very well as a medium to process things. If you've ever heard of memcached think of Redis along those lines. Like Memcached, it store values in memory so accessing and working with data in the store is incredibly fast.

这周我打算在redis上做文章,但是我想从简单的地方入手。从redis是什么开始吧,它是最小化键值存储区,它支持持久化数据同时作为处理事情的介质它同样工作得很棒。如果你听过memcached,那么想想上面的那些话吧。和memcached类似,它在内存中存储值,这样访问和操作数据都可以变得难以置信的快。

I've mentioned it in the past when talking about working with celery. It's great for usage with message queues because of the speed and many data sets. With that outlined, let's get into a working example to hook you in.

我曾在一篇博文中提到用celery工作。celery非常适合在高速和大量数据的消息队列中使用。这些都是题外话了,让咱们开始示例吧。

Building a Chatroom

One of the cool things that Redis supplies out of the box is a pub/sub module. You can connect to the Redis database and then set your script to subscribe to a specific channel. When subscribed, other users can publish content to that channel and the results will be collected and available for the channel. This is how chatrooms work. You subscribe to a certain room, and users publish content which is then printed to the room.

First of all, let's make sure we have Redis installed:

创建聊天室

redis应用最酷的一件事是pub/sub(发布/订阅)模块。你可以连接到redis然后设置你的脚本订阅你想要的频道。当订阅成功后,其他用户就可以发布内容到该频道、收集频道结果和可用频道。聊天室就是这么工作的:你进入到一个房间,房间内的用户发布将要在聊天室中输出的内容。

首先,确保已经安装了redis

$ sudo apt-get install redis-server
$ sudo redis-server start
$ redis-cli PING
PONG


If those commands work for you, then you're all setup!

I'm going to be using the awesome redis-py library to do this in Python. To get started, use pip to install the dependency:

如果上面的命令都执行了,那么你已经完成redis安装了

接下来我要在python中使用令人惊叹的redis-py库。首先,使用pip命令安装redis

$ pip install redis

With that done, let's create our first file. Make a file named settings.py

完成安装后,让我们创建第一个文件,命名为settings.py

import redisconfig = {    'host': 'localhost',    'port': 6379,    'db': 0,}r = redis.StrictRedis(**config)


Let's break this down:

  • Import redis to use in our app.

  • Create a config dictionary pointing to our Redis instance. Since the default Redis instance is located at localhost:6379 we're good to go. I also define the 0 database for this example but you can use any number up to 99 I believe.

  • Create a Redis object using the StrictRedis class based on our config. redis-py exposes two client classes that implement the commands and the StrictRedis class attempts to adhere to the official command syntax.

This basic config will get us our instance so that we can use it in our other app files. Let's see them.

Create a new file called pub.py:

庖丁解牛:

  • 导入redis到app配置文件中

  • 创建一个redis配置字典,用于redis实例。因为默认的redis实例是指向localhost:6379。本例中我也定义了数据库0,你可以使用任何0-99的数字。

  • 使用StrictRedis类创建redis对象。redis-py提供了2个客户端类来实现命令,并且StrictRedis类总是设法遵守官方命令语法。

这个基本配置让我们获得了redis实例,这样我们就能在我们的其他app文件中使用了

接下来我们创建一个新文件命名为 pub.py


from settings import rimport sysif __name__ == '__main__':    name = sys.argv[1]    channel = sys.argv[2]    print 'Welcome to {channel}'.format(**locals())    while True:        message = raw_input('Enter a message: ')        if message.lower() == 'exit':            break        message = '{name} says: {message}'.format(**locals())        r.publish(channel, message)

And breaking this example down:

  • We import our settings Redis object and the sys module. We then identify that our script should take two arguments after the filename. The first is the name which will be the username. The second is the channel.

  • After we get those, we jump into an infinite while loop which will ask the user for a message.

  • We add a clause to break the look by typing exit.

  • We then format the message based on the name and publish the message with the Redis object.

The only new thing here is this publish() method which allows us to select the channel and the message to pass. When we do so, all participants subscribed to the channel will get our messages. Let's see our subscriber now.

Create a new file called sub.py:

庖丁解牛:

  • 导入redis对象和sys模块。接下来又为脚本定义2个参数。第一个参数是将要成为用户名的name参数,第二个是频道channel.

  • 定义好这些后,将进入无限的while循环中获取消息

  • 添加子句来退出循环,通过输入的exit字符串中断循环

  • 根据name格式化消息,使用redis实例对象发布该消息

        在这里唯一要做的是publish()方法,该方法允许我们选择频道并传递消息。这样所有订阅该频道的的用户都将获取到消息。下面是订阅部分了

创建一个新文件,命名为sub.py

from settings import rimport sysif __name__ == '__main__':    channel = sys.argv[1]    pubsub = r.pubsub()    pubsub.subscribe(channel)    print 'Listening to {channel}'.format(**locals())    while True:        for item in pubsub.listen():            print item['data']

And one last break down will tell us that:

  • We import the same things and take a channel as our CLI argument.

  • We then use the redis-py pubsub() method to create a new pubsub instance. On that we have access to the subscribe() method which allows us to listen to a channel.

  • Jumping into an infinite while loop, we find items based on the listen() method and when we get them we print their data.

Very simple and the best thing is that the app is done. Go back to your terminal and open three windows. First off, start the subscriber:

庖丁解牛:

  • 和pub.py一样导入相同的模块,并且带上一个频道作为命令行参数

  • 使用redis-py的pubsub()方法创建一个新的pubsub实例对象。这样就能访问subscribe()订阅方法来监听频道。

  • 进入无限循环中,通过listen()方法获取消息并打印。(listen方法是阻塞的,也可使用get_message获取消息非阻塞消息)

   如此简单就完成了,现在打开三个终端窗口。先启动订阅:

$ python sub.py PYTHONListening to PYTHON

As you see, this continues to run and waits for messages to be published. Let's give it some messages. In another terminal window run:

如你所见,持续运行并等待发布过来的消息。接下来在另一终端窗口输入消息:

$ python pub.py Dan PYTHONWelcome to PYTHONEnter a message:

So far so good. Test it out by typing a message and watch the subscriber terminal window. You should see messages from one terminal appearing in the other terminal now! Let's open a third terminal window and make it act like a real chatroom.

到目前为止,一切正常,输入消息测试并观察订阅终端窗口。可以看到消息从一个终端出现在另一终端了。打开第三个终端窗口,演示一个聊天室。

$ python pub.py Jesse PYTHONWelcome to PYTHONEnter a message:

Now messages from one terminal window will be from Dan and the other will be from Jesse. Since our subscriber is just listening to the channel, we can have any number of users in this room. Try typing in both publisher windows and see the messages show up with the subscriber.

Nice and simple.

现在消息是来自一个Dan的和另一个来自Jesse的终端。因为订阅方监听了该频道,这样在这个房间里就可以有大量的用户。尝试在发布者窗口输入,并在订阅者中显示。

漂亮而简洁

Conclusion

        As you see, we didn't have to do much at all to get a chatroom example built in Redis. Of course, Redis does a lot more than just the pub/sub pattern for us and I'll be elaborating more on that this week. For now, play around with this example and if you want to see some more Redis jump into the Redis CLI by typing redis-cli in your terminal.


总结

如你所见,使用redis我们不必为聊天室例子做太多。当然,redis能做的比pub/sub模式还要多。我打算利用这周做更多的事情。到现在,只做了这个例子,如果你想见识更多Redis,那就在你的终端输入redis-cli进入Redis客户端吧,