使用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 相关文章推荐
wxPython 入门教程
Oct 07 Python
Python3.0与2.X版本的区别实例分析
Aug 25 Python
Pythont特殊语法filter,map,reduce,apply使用方法
Feb 27 Python
使用Python内置的模块与函数进行不同进制的数的转换
Mar 12 Python
Python找出list中最常出现元素的方法
Jun 14 Python
对dataframe进行列相加,行相加的实例
Jun 08 Python
如何利用Python开发一个简单的猜数字游戏
Sep 22 Python
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
Oct 12 Python
在notepad++中实现直接运行python代码
Dec 18 Python
Django实现从数据库中获取到的数据转换为dict
Mar 27 Python
opencv python 图片读取与显示图片窗口未响应问题的解决
Apr 24 Python
Python中random模块常用方法的使用教程
Oct 04 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中防止SQL注入攻击和XSS攻击的两个简单方法
2010/04/15 PHP
PHP微信模板消息操作示例
2017/06/29 PHP
让mayfish支持mysqli数据库驱动的实现方法
2010/05/22 Javascript
jQuery Autocomplete自动完成插件
2010/07/17 Javascript
jquery 插件学习(五)
2012/08/06 Javascript
js如何设置在iframe框架中指定div不显示
2013/12/04 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
2014/06/15 Javascript
JQuery节点元素属性操作方法
2015/06/11 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
2015/10/26 Javascript
javascript实现C语言经典程序题
2015/11/29 Javascript
JavaScript实现计数器基础方法
2017/10/10 Javascript
Vue封装一个简单轻量的上传文件组件的示例
2018/03/21 Javascript
详解React 的几种条件渲染以及选择
2018/10/23 Javascript
Python 类与元类的深度挖掘 II【经验】
2016/05/06 Python
Python自定义函数定义,参数,调用代码解析
2017/12/27 Python
django DRF图片路径问题的解决方法
2018/09/10 Python
python 堆和优先队列的使用详解
2019/03/05 Python
Python爬虫学习之获取指定网页源码
2019/07/30 Python
python递归下载文件夹下所有文件
2019/08/31 Python
Django Session和Cookie分别实现记住用户登录状态操作
2020/07/02 Python
基于python图书馆管理系统设计实例详解
2020/08/05 Python
Jupyter notebook命令和编辑模式常用快捷键汇总
2020/11/17 Python
python 利用matplotlib在3D空间绘制二次抛物面的案例
2021/02/06 Python
Python读写Excel表格的方法
2021/03/02 Python
美国摄影爱好者购物网站:Focus Camera
2016/10/21 全球购物
家庭户外服装:Hawkshead
2017/11/02 全球购物
中文专业毕业生自荐信
2013/10/28 职场文书
机械专业毕业生自荐信
2013/11/02 职场文书
招聘专员岗位职责
2014/03/07 职场文书
三好学生个人先进事迹材料
2014/05/17 职场文书
政府个人对照检查材料思想汇报
2014/10/08 职场文书
阿凡达观后感
2015/06/10 职场文书
python爬虫--selenium模块
2021/03/31 Python
Nginx内网单机反向代理的实现
2021/11/07 Servers
使用 CSS 轻松实现一些高频出现的奇形怪状按钮
2021/12/06 HTML / CSS
Win11怎么解除儿童账号限制?Win11解除微软儿童账号限制方法
2022/07/07 数码科技