使用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二叉树的实现实例
Nov 21 Python
深入理解python多进程编程
Jun 12 Python
Python 正则表达式入门(中级篇)
Dec 07 Python
Python3使用PyQt5制作简单的画板/手写板实例
Oct 19 Python
Python实现的基数排序算法原理与用法实例分析
Nov 23 Python
Python中生成器和迭代器的区别详解
Feb 10 Python
python3+dlib实现人脸识别和情绪分析
Apr 21 Python
Python实现定时自动关闭的tkinter窗口方法
Feb 16 Python
关于Python 的简单栅格图像边界提取方法
Jul 05 Python
tensorflow 保存模型和取出中间权重例子
Jan 24 Python
Python3 集合set入门基础
Feb 10 Python
Python编解码问题及文本文件处理方法详解
Jun 20 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
Phpbean路由转发的php代码
2008/01/10 PHP
PHP缩略图等比例无损压缩,可填充空白区域补充色
2011/06/10 PHP
教你如何解密 “ PHP 神盾解密工具 ”
2014/06/20 PHP
javascript 数据类型转换(parseInt,parseFloat)
2010/07/20 Javascript
HTML DOM的nodeType值介绍
2011/03/31 Javascript
JQuery循环滚动图片代码
2011/12/08 Javascript
jquery乱码与contentType属性设置问题解决方案
2013/01/07 Javascript
js AppendChild与insertBefore用法详细对比
2013/12/16 Javascript
js实现动态改变字体大小代码
2014/01/02 Javascript
JavaScript中Date.toSource()方法的使用教程
2015/06/12 Javascript
高性能JavaScript DOM编程(1)
2015/08/11 Javascript
Angularjs过滤器使用详解
2016/05/25 Javascript
利用JS实现文字的聚合动画效果
2017/01/22 Javascript
angular2 ng build部署后base文件路径问题详细解答
2017/07/15 Javascript
解决ionic和angular上拉加载的问题
2017/08/03 Javascript
JS实现的加减乘除四则运算计算器示例
2017/08/09 Javascript
Angular入口组件(entry component)与声明式组件的区别详解
2018/04/09 Javascript
详解Vue项目在其他电脑npm run dev运行报错的解决方法
2018/10/29 Javascript
详解vue中async-await的使用误区
2018/12/05 Javascript
通过cordova将vue项目打包为webapp的方法
2019/02/02 Javascript
微信小程序云开发修改云数据库中的数据方法
2019/05/18 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
[01:22]DOTA2神秘商店携大量周边降临完美大师赛
2017/11/07 DOTA
运用TensorFlow进行简单实现线性回归、梯度下降示例
2018/03/05 Python
python中实现将多个print输出合成一个数组
2018/04/19 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
python-web根据元素属性进行定位的方法
2019/12/13 Python
pytorch中获取模型input/output shape实例
2019/12/30 Python
哥德堡通行证:Gothenburg Pass
2019/12/09 全球购物
XMLHttpRequest对象在IE和Firefox中创建方式有没有不同
2016/03/23 面试题
建筑实习自我鉴定
2013/10/18 职场文书
部队万能检讨书
2014/02/20 职场文书
小学师德师风演讲稿
2014/09/02 职场文书
秋季校运会广播稿100字
2014/09/18 职场文书
护士长2014年终工作总结
2014/11/11 职场文书
2014年底工作总结
2014/12/15 职场文书