一、基本的文件結構
二、文件內容
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;
//重構date的Format屬性
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("yyyy年MM月dd 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)
# 定義接收/發送聊天消息的視圖處理類,繼承自websocket的WebSocketHandler
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()