Tornado——WebSocket長連接—聊天室案例

一、基本的文件結構


二、文件內容

1.index.html

該文件爲聊天室登錄頁面,通過在該頁面輸入的暱稱,用以在聊天頁面展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄首頁</title>
    <link rel="stylesheet" href="/static/libs/bootstrap/bootstrap-3.3.7-dist/css/bootstrap.css">
    <script src="/static/libs/jquery/jquery-2.2.4.js"></script>

</head>
<body>
<div class="container">
    <div class="panel panel-primary" style="width:60%;">
        <div class="panel panel-heading">
            聊天室個人登錄
        </div>
        <div class="panel panel-body">
            <form class="form-horizontal" method="get" action="/login" style="width:80%">
                <div class="form-group">
                    <label for="nickname" class="col-sm-2 control-label">暱稱</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="nickname" placeholder="請輸入暱稱" name="nickname">
                    </div>
                </div>
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" class="btn btn-default">登錄</button>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>
頁面效果:

2.chat.html

該頁面是聊天室頁面,重要顯示接收數據和發送數據
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>python1709聊天室</title>
    <link rel="stylesheet" href="/static/libs/bootstrap/bootstrap-3.3.7-dist/css/bootstrap.css">
    <link rel="stylesheet" href="/static/app/css/index.css">
    <script src="/static/libs/jquery/jquery-2.2.4.js"></script>
</head>
<body>
<div class="container">
    <div id="window">
        <div class="panel panel-info">
            <div class="panel-heading">
                聊天室
            </div>
            <div class="content">
                <div class="left">
                    <div id="personal">個人形象區</div>
                    <img src="/static/app/image/3.jpg" width="300" height="455">
                </div>
                <div class="receive">

                </div>
                <div class="send">
                    <textarea name="send_content" id="send_content" required> </textarea>
                    <button  id="btn" >發送</button>
                </div>
            </div>

        </div>
    </div>
</div>
<script>
    // 創建一個websocket長連接對象
    var _websocket= new WebSocket('ws://192.168.11.85:8000/chat')
    //發送消息
    $('#btn').click(function(){
        //獲取消息內容
        $msg=$('#send_content').val();
        //發送消息
        _websocket.send($msg);
         $("#msg").val('');
    })
    //接收消息,當消息更新時自動觸發
    _websocket.onmessage=function(e){
        console.log(e)
        var $content=e.data;
        //重構dateFormat屬性
        Date.prototype.Format = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //        "H+": this.getHours(), //小時
        "m+": this.getMinutes(), //        "s+": this.getSeconds(), //        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}
        var date=new Date();
        var $time=date.Format("yyyyMMdd HH:mm:ss");
        var $p1=$('<p>').text($content);
        var $p2=$('<p>').text($time);
        $('.receive').append($p2).append($p1)

    }

</script>
</body>
</html>
頁面效果:

3.main.py 文件


'''
websocket長連接 聊天室案例
'''
# 引入需要的模塊
from tornado.web import RequestHandler, Application,Cookie
from tornado.httpserver import HTTPServer
from tornado.websocket import WebSocketHandler
from tornado.ioloop import IOLoop

class BaseHandler(RequestHandler):
    pass

# 定義首頁視圖處理類,提示用戶登錄
class IndexHandler(BaseHandler):
    def get(self):
        self.render('index.html')

# 定義登錄視圖處理類
class LoginHandler(BaseHandler):
    def get(self):
        # 獲取用戶登錄的暱稱
        nickname=self.get_argument('nickname')
        # 將用戶登錄的暱稱保存在cookie中,安全cookie
        self.set_secure_cookie('nickname',nickname,expires_days=None)
        self.render('chat.html',nickname=nickname)


# 定義接收/發送聊天消息的視圖處理類,繼承自websocketWebSocketHandler
class ChatHandler(WebSocketHandler):
    # 定義一個集合,用來保存在線的所有用戶
    online_users = set()
    # 從客戶端獲取cookie信息


    # 重寫open方法,當有新的聊天用戶進入的時候自動觸發該函數
    def open(self):
        # 當有新的用戶上線,將該用戶加入集合中
        self.online_users.add(self)
        # 將新用戶加入的信息發送給所有的在線用戶
        for user in self.online_users:
            user.write_message('%s】進入了聊天室' % self.request.remote_ip)

    # 重寫on_message方法,當聊天消息有更新時自動觸發的函數
    def on_message(self, message):
        # 將在線用戶發送的消息通過服務器轉發給所有的在線用戶
        for user in self.online_users:
            user.write_message('%s:%s' % (self.request.remote_ip, message))

    # 重寫on_close方法,當有用戶離開時自動觸發的函數
    def on_close(self):
        # 先將用戶從列表中移除
        self.online_users.remove(self)
        # 將該用戶離開的消息發送給所有在線的用戶
        for user in self.online_users:
            user.write_message('%s】離開了聊天室~' % self.request.remote_ip)

    def check_origin(self, origin):
        return  True

# 程序運行入口
if __name__=='__main__':
    import os
    BASE_DIR=os.path.dirname(__file__)
    app=Application([
        (r'/',IndexHandler),
        (r'/login',LoginHandler),
        (r'/chat',ChatHandler),
    ],
    template_path=os.path.join(BASE_DIR,'templates'),
    static_path=os.path.join(BASE_DIR,'static'),
    debug=True,
    login_url='/login',
    cookie_secret='CPFL2FJOTQGzR/8DXZEyfAjxS9hSTk0Bs0f/A12RMnwI8UvYUk5NAbNH/wNdkTJ8')
    server=HTTPServer(app)
    server.listen(8000)
    IOLoop.current().start()






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章