使用Python的Tornado框架实现一个一对一聊天的程序


Posted in Python onApril 25, 2015

按思路来聊:

类似微信,点击用户可以进入一对一聊天页面;另有聊天框列表包含所有存在聊天记录的一对一聊天框,点击进入聊天页面。
【数据结构】

因为双方都有聊天记录,所以每一个聊天实际上得储存两份,设计的数据结构如下:

A :

user_a = {“id”:1,”name”:”A”}

B :

user_b = {“id”:2,”name”:”B”}

A的聊天记录:

chat_a = { “id”:1, “user”:1, “who”:2, “name”:”B”, “new”:0, msg:[]}

B的聊天记录:

chat_b = { “id”:2, “user”:2, “who”:1, “name”:”A”, “new”:0, msg:[]}

msg实际上是个list,结构如下:msg = { “user”:发送者id, “name”:发送者name, “date”:发送时间, “content”:消息内容 }
【业务逻辑】

当A点击好友列表中B的名字?>进入聊天框(根据双方id通过字段user、who找到对应chat_a,chat = coll.find_one({“user”:user_a[‘id'], “who”:user_b[‘id']});如果该chat不存在,则利用双方id创建chat_a)

发送消息(更新chat_a和chat_b,如果chat_b不存在则创建chat_b;如果chat_b不在线则更新chat_b[‘new'] = 1)

A删除聊天框(删除chat_a)
【记录客户端连接】

由于是多个一对一聊天,所以不能直接用教程里的set来记录连接。

最后的决定是用一个 dict,用双方用户id拼接的字符串作为key,用list存客户端连接。

...SocketHandler(...):

chats = dict()
...
def on_open(self):
  ...
  #通过双方id来生成一个独一无二的字符串
  min = user_a['id']
  max = user_b['id']
  if min >max:
    max = user_a['id']
    min = user_b['id']
  key = str(user_a['id'])+"_"+str(user_b['id'])
  #判断当前会话是否存在,存在则添加当前用户
  if key in chats:
    SocketHandler.chats[key].append(self)
  #不存在则创建会话,并将当前用户添加进去
  else
    SocketHandler.chats[key] = [self]

【发送消息】

从客户端调用send函数,在服务端on_message函数中接受参数后更新双方聊天记录。之后调用send_to_all(key, message)来更新聊天窗口。
【发通知/更新聊天窗口】

更新数据库里的聊天记录后还要在聊天窗口更新html,所以需要通知该会话的连接者。

根据我们记录连接者的方式,对应的通知函数如下:

def send_to_all(key,message):
  for user in SocketHandler.chats[key]:
    user.write_message(json.dumps(message))

【关闭连接】

根据我们记录连接者的方式,对应的关闭函数如下:

def on_close(self):
  ...
  #用on_open函数中的方法构造key
  if key in SocketHandler.chats:
    SocketHandler.chats[key].remove(self)#删除当前连接
    if len(SocketHandler.chats[key]) == 0:
      del SocketHandler.chats[key]#当会话无连接者则删除会话

经过上面的改造,就实现多个一对一聊天功能

Python 相关文章推荐
构建Python包的五个简单准则简介
Jun 15 Python
Python2实现的图片文本识别功能详解
Jul 11 Python
Python Flask前后端Ajax交互的方法示例
Jul 31 Python
Python线程下使用锁的技巧分享
Sep 13 Python
对Python _取log的几种方式小结
Jul 25 Python
用Python画一个LinkinPark的logo代码实例
Sep 10 Python
python3反转字符串的3种方法(小结)
Nov 07 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
Mar 30 Python
Django使用Profile扩展User模块方式
May 14 Python
浅谈Python 函数式编程
Jun 20 Python
matplotlib.pyplot.plot()参数使用详解
Jul 28 Python
撤回我也能看到!教你用Python制作微信防撤回脚本
Jun 11 Python
使用Python发送邮件附件以定时备份MySQL的教程
Apr 25 #Python
安装Python的web.py框架并从hello world开始编程
Apr 25 #Python
用Python编写一个基于终端的实现翻译的脚本
Apr 24 #Python
Python的Bottle框架中获取制定cookie的教程
Apr 24 #Python
利用Python的装饰器解决Bottle框架中用户验证问题
Apr 24 #Python
在Python中使用mongoengine操作MongoDB教程
Apr 24 #Python
python使用arp欺骗伪造网关的方法
Apr 24 #Python
You might like
php+mysqli实现批量替换数据库表前缀的方法
2014/12/29 PHP
php从身份证获取性别和出生年月
2017/02/09 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
PHP设计模式概论【概念、分类、原则等】
2020/05/01 PHP
Jquery中dialog属性小记
2010/09/03 Javascript
基于jquery的滚动条滚动固定div(附演示下载)
2012/10/29 Javascript
JS模板实现方法
2013/04/03 Javascript
jquery 根据name名获取元素的value值
2015/02/27 Javascript
基于JS实现无缝滚动思路及代码分享
2016/06/07 Javascript
js 自带的 map() 方法全面了解
2016/08/16 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
2017/03/01 Javascript
vuejs 制作背景淡入淡出切换动画的实例
2018/09/01 Javascript
使用Angular Cli如何创建Angular私有库详解
2019/01/30 Javascript
python处理文本文件实现生成指定格式文件的方法
2014/07/31 Python
在Python的Flask框架中实现全文搜索功能
2015/04/20 Python
Python的迭代器和生成器
2015/07/29 Python
python2.7 mayavi 安装图文教程(推荐)
2017/06/22 Python
python opencv之SURF算法示例
2018/02/24 Python
Python Django 页面上展示固定的页码数实现代码
2019/08/21 Python
Python join()函数原理及使用方法
2020/11/14 Python
如何通过安装HomeBrew来安装Python3
2020/12/23 Python
CSS3的 fit-content实现水平居中
2017/09/07 HTML / CSS
在HTML5 canvas里用卷积核进行图像处理的方法
2018/05/02 HTML / CSS
日本最佳原创设计品牌:Felissimo(芬理希梦)
2019/03/19 全球购物
印度尼西亚最好的小工具在线商店:Erafone.com
2019/03/26 全球购物
趣天网日本站:Qoo10 JP
2019/09/18 全球购物
留学生如何写好自荐信
2013/12/27 职场文书
致标枪运动员广播稿
2014/02/06 职场文书
护校行动方案
2014/05/31 职场文书
反四风个人对照检查材料
2014/09/26 职场文书
婚礼答谢礼品
2015/01/20 职场文书
通知的格式范文
2015/04/27 职场文书
入党积极分子培养人意见
2015/06/02 职场文书
中秋联欢会主持词
2015/07/04 职场文书
win11怎么用快捷键锁屏? windows11锁屏的几种方法
2021/11/21 数码科技
MySQL导致索引失效的几种情况
2022/06/25 MySQL