博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tornado+websocket+mongodb实现在线视屏文字聊天
阅读量:6276 次
发布时间:2019-06-22

本文共 4233 字,大约阅读时间需要 14 分钟。

最近学了tornado和mongo,所以结合websocket 实现一个聊天功能,从而加深一下相关知识点的印象

1.websocket概览

webscoket是一种全双工通信模式的协议,客户端连接服务端先通过tcp,http转为webscoket协议后,客户端和服务端都可以主动推送消息给另一端,这也是和http协议(服务端只能被动接收消息,无法主动推送消息给客户端)最大的区别。

2.tornado概览

tornado是一种异步网络库的python web框架,最初在 FriendFeed上开发,通过使用非阻塞网络I/O,tornado可以扫描数以万计打开的链接,让它成为给每个用户一个长链接的理想选择。

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking network I/O, Tornado can scale to tens of thousands of open connections, making it ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user.

3.实现在线聊天功能概览

  • 判断对方是否在线,保存离线消息,在线时推送过去,并删除离线消息
  • 不保存在线消息
  • 单点登录模式的聊天
  • 同时和多人点对点聊天

 4.后端代码

import redisimport tornado.httpserverimport tornado.ioloopimport tornado.webfrom motor import motor_tornadofrom tornado import websocketfrom tornado.gen import coroutinefrom conf import Configclass WebHandler(websocket.WebSocketHandler):    # 在线用户dict    all_user = {}    def initialize(self, mongo, redis):        self.mongo = mongo        self.redis = redis    @property    def db(self):        return self.mongo.get_database('rgc')    @property    def col(self):        return self.db.get_collection('web')    def check_origin(self, origin):        return True  # 允许WebSocket的跨域请求    @coroutine    def on_message(self, message):        #因为没有登录相关功能,每次传输都 用 # 拼接 发送者,消息,接受者        resu = str.split(message, '#')        name = resu[0]        val = resu[1]        to = resu[2]        # 判断对方是否在线        if 'name:{}'.format(to) not in list(self.all_user.keys()):            self.write_message('Out Line')            # 存储消息到db            # if not self.redis.hget('name_list', '{}:{}'.format(name, to)):            #     self.redis.hset('name_list', '{}:{}'.format(name, to), 1)            self.col.insert({
'name': '{}:{}'.format(name, to), 'msg': val}) else: # 发送最新消息 self.all_user['name:{}'.format(to)].write_message(val) # 检查是不是第一次上线 if 'name:{}'.format(name) not in list(self.all_user.keys()): # 给自己发送历史消息 his_one = self.col.find({
'name': '{}:{}'.format(to, name)}, {
'msg': 1, '_id': 0}) for it in (yield his_one.to_list(100)): self.write_message(it['msg']) # 删除历史消息 self.col.delete_many({
'name': '{}:{}'.format(to, name)}) # 单点登录聊天 self.all_user.update({
'name:{}'.format(name): self}) # 发给自己 self.write_message('send success') def open(self): pass def on_close(self): # 当客户端关闭连接时,去除内存中保存的用户,让其离线 key = None for k, v in self.all_user.items(): if v == self: key = k break if key: self.all_user.pop(key) print('{} out line'.format(key))class HtmlHandler(tornado.web.RequestHandler): def get(self): self.render("static/index.html")class StaticHandler(tornado.web.RequestHandler): def get(self, file_url): self.render("static/{}".format(file_url))def make_app(): settings = {
'cookie_secret': 'dfdfdfd', 'xsrf_cookies': True, 'debug': True} other_db = {
'mongo': motor_tornado.MotorClient(**Config.get('MONGO_CONF')), 'redis': redis.StrictRedis()} return tornado.web.Application([ (r'/web', WebHandler, other_db), (r'/', HtmlHandler), (r'/static/(.*)', StaticHandler) ], **settings)if __name__ == '__main__': app = make_app() http_server = tornado.httpserver.HTTPServer(app) ip='127.0.0.1' port = 8000 http_server.bind(8000, ip) http_server.start(1) print('server start! http://{}:{}'.format(ip, port)) tornado.ioloop.IOLoop.current().start()

 5.前端技术:

前端主要使用到了  MediaSource,Blob 等技术,发送视频大致思路为:先获取视频文件发送给服务端,然后从服务端发送给另一个客户端,客户端进行视频解析后播放出来。

效果展示:(因为开启浏览器视频功能,必须在https环境或者本地回环地址(127.0.0.1)中才可),所以本次效果展示是在本地进行展示

  • 谷歌浏览器(因为我是后端开发,前端代码没有做兼容,并且界面有点丑)开启两个网页,输入  http://127.0.0.1:8000/
  • 进入界面后,在name里输入自己的姓名,message中输入 发送给对方的消息,to 里面输入 对方名字,然后点击发送

     

  • lucy发送工tom的信息,在发送信息时,系统检测到tom给她发了离线消息,所以一并返回给lucy。

     

  • 视频发送测试,name和to用的还是之前的:
  • 看一下 浏览器控制台 websocket接口的相关内容:

  • 可以看到所有的交流都是在一个 websocket连接中,双方可以互发消息

 项目代码所在地: 

 

转载于:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_810days.html

你可能感兴趣的文章
阿里感悟(十八)- 应届生Review
查看>>
《计算广告:互联网商业变现的市场与技术》一第一部分 在线广告市场与背景...
查看>>
话说模式匹配(5) for表达式中的模式匹配
查看>>
《锋利的SQL(第2版)》——1.7 常用函数
查看>>
《Arduino家居安全系统构建实战》——1.5 介绍用于机器学习的F
查看>>
jquery中hover()的用法。简单粗暴
查看>>
线程管理(六)等待线程的终结
查看>>
spring boot集成mongodb最简单版
查看>>
DELL EqualLogic PS存储数据恢复全过程整理
查看>>
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>
Sphinx 配置文件说明
查看>>
数据结构实践——顺序表应用
查看>>
python2.7 之centos7 安装 pip, Scrapy
查看>>
机智云开源框架初始化顺序
查看>>
Spark修炼之道(进阶篇)——Spark入门到精通:第五节 Spark编程模型(二)
查看>>
一线架构师实践指南:云时代下双活零切换的七大关键点
查看>>
ART世界探险(19) - 优化编译器的编译流程
查看>>