使用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之不要红头文件(2)
Sep 28 Python
Python生成8位随机字符串的方法分析
Dec 05 Python
Python合并多个Excel数据的方法
Jul 16 Python
新年快乐! python实现绚烂的烟花绽放效果
Jan 30 Python
使用python list 查找所有匹配元素的位置实例
Jun 11 Python
Windows下pycharm创建Django 项目(虚拟环境)过程解析
Sep 16 Python
Python如何读写二进制数组数据
Aug 01 Python
python与c语言的语法有哪些不一样的
Sep 13 Python
pymysql模块使用简介与示例
Nov 17 Python
基于Django集成CAS实现流程详解
Nov 28 Python
Python 实现PS滤镜的旋涡特效
Dec 03 Python
pytorch锁死在dataloader(训练时卡死)
May 28 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 获取select下拉列表框的值
2010/05/08 PHP
完美解决PHP中的Cannot modify header information 问题
2013/08/12 PHP
php实现的简易扫雷游戏实例
2015/07/09 PHP
php单例模式的简单实现方法
2016/06/10 PHP
详解EventDispatcher事件分发组件
2016/12/25 PHP
PHP实现会员账号单唯一登录的方法分析
2019/03/07 PHP
ext 同步和异步示例代码
2009/09/18 Javascript
js的表单操作 简单计算器
2011/12/29 Javascript
JQuery判断HTML元素是否存在的两种解决方法
2013/12/26 Javascript
js中的onchange和onpropertychange (onchange无效的解决方法)
2014/03/08 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
2015/03/24 Javascript
详解JavaScript中的blink()方法的使用
2015/06/08 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖动基本操作
2015/11/30 Javascript
js判断手机访问或者PC的几个例子(常用于手机跳转)
2015/12/15 Javascript
wap手机端解决返回上一页的js实例
2016/12/08 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
[01:16:28]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第二场 2月23日
2021/03/11 DOTA
win7安装python生成随机数代码分享
2013/12/27 Python
Python中二维列表如何获取子区域元素的组成
2017/01/19 Python
python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法(实例代码)
2020/01/08 Python
Python基于staticmethod装饰器标示静态方法
2020/10/17 Python
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
Banana Republic英国官网:香蕉共和国,GAP集团旗下偏贵族风
2018/04/24 全球购物
日本快乐生活方式购物网站:Shop Japan
2018/07/17 全球购物
初三化学教学反思
2014/01/23 职场文书
大学生作弊检讨书
2014/02/19 职场文书
《他得的红圈圈最多》教学反思
2014/04/24 职场文书
三严三实对照检查材料
2014/09/22 职场文书
不服从公司安排检讨书
2014/09/24 职场文书
优秀教育工作者事迹材料
2014/12/24 职场文书
给客户的感谢信
2015/01/21 职场文书
2015年预算员工作总结
2015/05/14 职场文书
监守自盗观后感
2015/06/10 职场文书
《成长的天空》读后感3篇
2019/12/06 职场文书
win10搭建配置ftp服务器的方法
2022/08/05 Servers