tornado+websocket+mongodb实现在线视屏文字聊天

最近学了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 redis
import tornado.httpserver
import tornado.ioloop
import tornado.web
from motor import motor_tornado
from tornado import websocket
from tornado.gen import coroutine

from conf import Config

class 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://github.com/Rgcsh/tornado_websocket

原文地址:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_810days.html

时间: 2024-11-08 06:28:34

tornado+websocket+mongodb实现在线视屏文字聊天的相关文章

Node.js+websocket+mongodb实现即时聊天室

ChatRoom Node.js+websocket+mongodb实现即时聊天室 A,nodejs简介:Node.js是一个可以让javascript运行在服务器端的平台,它可以让javascript脱离浏览器的束缚运行在一般的服务器下面,你可以用Node.js轻松地进行服务器端应用的开发.Node.js是一个为实时Web应用开发而诞生的平台,它充分考虑了在实时响应和超大规模数据下架构的可扩展性,这使得它摒弃了传统的平台依靠多线程来实现高并发的的设计思路,而采用了单线程,异步式I/O和事件驱动

Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器

效果图如下: (PS本来是要给大家穿gif动态图的,无奈太大了,没法上传) 功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能 实现的思路: 在主布局中放置一个SurfaceView,在SurfaceView中放置一个MediaPlayer ,在其下方自定义一个MediaController,不过也不能称之为MediaController,使用的是PupupWindow来实现的,在PupupWindow布局中放置几个textView,Button,最重要的使我们的SeekBar控件,创

ffmpeg 编码(视屏)

分析ffmpeg_3.3.2 muxing 1:分析主函数,代码如下: 1 int main(int argc, char **argv) 2 { 3 OutputStream video_st = { 0 }, audio_st = { 0 }; 4 const char *filename; 5 AVOutputFormat *fmt; 6 AVFormatContext *oc; 7 AVCodec *audio_codec, *video_codec; 8 int ret; 9 int

Snipaste强大离线/在线截屏软件的下载、安装和使用

步骤一: https://zh.snipaste.com/  ,去此官网下载. 步骤二:由于此是个绿色软件,直接解压即可. 步骤三:使用,见官网.ttps://zh.snipaste.com  按F1开始截屏 感谢下面哥的精彩微信文章 http://mp.weixin.qq.com/s?__biz=MzIwNzYwODYwMw==&mid=2247483903&idx=1&sn=02121fe920320bbe7b2fae012a18e70a&chksm=970e8f8ba

phonegap 捕获图片,音频,视屏 api capture

一. capture Api 简单介绍 capture 对象用于获取视屏,音频和图像,它是一个全局对象,通过 navigator.device.capture 来访问 方法: capture.captureAudio           捕获音频 capture.captureImage          捕获图片 capture.captureVideo          捕获视屏 MediaFile.getFormatData       获取媒体文件的格式信息 二. captureAudi

android录制视屏(预览,倒计时)

android用mediarecord录制视屏,可以设置视屏格式,大小,还有拍摄前预览,倒计时功能要自己用hander做. 1,CameraPreview.java //预览class public class CameraPreview extends SurfaceView implements Callback { private static final String TAG = "TAG-CameraPreview"; private SurfaceHolder mHolde

tornado websocket

近期在网上找了些websocket的资料看了下.node和tornado等等本身已经实现了websocket的封装,所以使用起来会比較简单,php假设想要写websocket还须要自己跑一整套流程,比較麻烦. 依据网上的资料写了一个简单的websocket的demo,果真炫酷掉渣天,我是用tornado,网上多是实现实时聊天室的样例,想要实现点对点的聊天功能还须要在send函数那里加条件,目測是依据浏览器用户的id去推断的.代码例如以下: 服务端代码: #!/usr/bin/python #co

实验6 在应用程序中播放音频和视屏

实验报告 课程名称 基于Android平台移动互联网开发 实验日期 4.15 实验项目名称 在应用程序中播放音频和视屏 实验地点 S3010 实验类型 □验证型    √设计型    □综合型 学  时 1学时 一.实验目的及要求(本实验所涉及并要求掌握的知识点) 实现在应用程序中处理音频和视频 实现播放音频,音频播放控制 实现播放视屏,视屏播放控制 使用service服务播放项目原文件的音乐 二.实验环境(本实验所使用的硬件设备和相关软件) (1)PC机 (2)操作系统:Windows XP

视屏录制

#import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVCaptureFileOutputRecordingDelegate> @property(nonatomic ,strong) AVCaptureFileOutput * outPut; @property(nonatomic ,strong)AVCaptureSessi