6

使用python和redis实现实时聊天室

 2 years ago
source link: https://limboy.me/posts/python-comet/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用python和redis实现实时聊天室

2011-10-26

实时的实现一般有 ajax long poll / iframe stream / websocket 这三种。websocket 有浏览器的限制;iframe 会使页面一直处于 loading 状态(如果没有这个限制,iframe stream 相比 long poll 还是比较有优势的); ajax long poll 因为它的跨浏览器特性,加上实现比较简单,所以不少的实时应用都选择了 long poll, 这里也选择 ajax long poll 来实现

放个截图先:

comet_chat.png

主要工具:python (flask / gevent / apscheduler) + redis

目前这个聊天室的功能还比较简单,可以实时更新全局在线用户,当前聊天室在线用户和聊天内容,都是通过一个 ajax 长连接实现的。在这个连接里定义了需要实时的内容,相应的内容一旦在服务端更新,可以马上推送到各个客户端。

实时最大的挑战在于如何能在服务端尽量简单,灵活地实现。因为越是简单,就越不容易滋生 bug,即使出现问题,查找起来也很方便;越是灵活,就越容易应付多变的需求。以聊天室为例,当新用户加入后需要更新所有客户端的当前成员列表;有成员退出后也要更新该列表。每个聊天室有了新内容后都要实时推到所有客户端;给某个用户发私信,对方也可以实时收到。这些如果处理地不好,很容易与当前的逻辑发生耦合,为将来的调整和 bug 的查找带来困难。

依靠强大的 redis,设计了这个简易的实时聊天室,基本架构如下:

comet_arch.png

匆忙完成了初步的代码,还有不少需要优化的地方,有些功能也还没加上(如私信的实时通知)。接下来的一段时间内会逐步完善,如果有更好的 idea,欢迎沟通 :)

代码地址:https://github.com/limboy/chat

如果使用过程中遇到什么问题,或有好的建议可以在这里反馈

version 0.2

  • 调整了实时的策略,抛弃 pubsub 模式,使用 zset+timestamp。同时修正了在聊天内容频繁发送时会丢部分信息的 bug
  • 添加了管理员角色(目前只能用于删除聊天室)
  • 修正重复名的 bug(无法完全避免,只能在登录时验证)

version 0.1.1

  • 调整了添加聊天室的体验
  • 更快的聊天内容显示速度
  • 可以删除自己创建的聊天室
  • bugfixes

version 0.1

intro

某天晚上打球回来,到家已将近 11 点,洗完澡,代码敲到 2 点左右倒下,天还没亮就被猫叫醒,醒来后就一直想如何改进这个聊天室,觉得能在一个页面实时看到每个聊天室的内容,还是很酷的,于是就按着这个想法实现了。

PS: 如果不是全新安装,需要执行 bin/python scripts/clear_key.py 来清除 redis cache

changelog

  • 可以自定义昵称
  • 调整了聊天页的内容和样式
  • 添加了 home 页(显示所有的聊天室,并实时更新每个聊天室的内容)
  • 使用 coffee-script 重写了 js 部分
  • bugfixes

screenshot

comet_home_0.1.png

comet_room_0.1.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK