一、基本的文件结构
width&#61;"300" height&#61;"455">div><div class&#61;"receive">div><div class&#61;"send"><textarea name&#61;"send_content" id&#61;"send_content" required> textarea><button id&#61;"btn" >发送button>div>div>div>div>
div>
<script>// 创建一个websocket长连接对象
var _websocket&#61; new WebSocket(&#39;ws://192.168.11.85:8000/chat&#39;)//发送消息
$(&#39;#btn&#39;).click(function(){//获取消息内容
$msg&#61;$(&#39;#send_content&#39;).val();//发送消息
_websocket.send($msg);$("#msg").val(&#39;&#39;);})//接收消息,当消息更新时自动触发
_websocket.onmessage&#61;function(e){console.log(e)var $content&#61;e.data;//重构date的Format属性
Date.prototype.Format &#61; function (fmt) {var o &#61; {"M&#43;": this.getMonth() &#43; 1, //月份
"d&#43;": this.getDate(), //日
"H&#43;": this.getHours(), //小时
"m&#43;": this.getMinutes(), //分
"s&#43;": this.getSeconds(), //秒
"q&#43;": Math.floor((this.getMonth() &#43; 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};if (/(y&#43;)/.test(fmt)) fmt &#61; fmt.replace(RegExp.$1, (this.getFullYear() &#43; "").substr(4 - RegExp.$1.length));for (var k in o)if (new RegExp("(" &#43; k &#43; ")").test(fmt)) fmt &#61; fmt.replace(RegExp.$1, (RegExp.$1.length &#61;&#61; 1) ? (o[k]) : (("00" &#43; o[k]).substr(("" &#43; o[k]).length)));return fmt;
}var date&#61;new Date();var $time&#61;date.Format("yyyy年MM月dd HH:mm:ss");var $p1&#61;$(&#39;
&#39;).text($content);var $p2&#61;$(&#39;
&#39;).text($time);$(&#39;.receive&#39;).append($p2).append($p1)}script>
body>
html>
页面效果:
3.main.py 文件
&#39;&#39;&#39;
websocket长连接 聊天室案例
&#39;&#39;&#39;
# 引入需要的模块
from tornado.web import RequestHandler, Application,COOKIE
from tornado.httpserver import HTTPServer
from tornado.websocket import WebSocketHandler
from tornado.ioloop import IOLoopclass BaseHandler(RequestHandler):pass
# 定义首页视图处理类&#xff0c;提示用户登录
class IndexHandler(BaseHandler):def get(self):self.render(&#39;index.html&#39;)# 定义登录视图处理类
class LoginHandler(BaseHandler):def get(self):# 获取用户登录的昵称
nickname&#61;self.get_argument(&#39;nickname&#39;)# 将用户登录的昵称保存在COOKIE中&#xff0c;安全COOKIE
self.set_secure_COOKIE(&#39;nickname&#39;,nickname,expires_days&#61;None)self.render(&#39;chat.html&#39;,nickname&#61;nickname)# 定义接收/发送聊天消息的视图处理类&#xff0c;继承自websocket的WebSocketHandler
class ChatHandler(WebSocketHandler):# 定义一个集合&#xff0c;用来保存在线的所有用户
online_users &#61; set()# 从客户端获取COOKIE信息
# 重写open方法&#xff0c;当有新的聊天用户进入的时候自动触发该函数
def open(self):# 当有新的用户上线&#xff0c;将该用户加入集合中
self.online_users.add(self)# 将新用户加入的信息发送给所有的在线用户
for user in self.online_users:user.write_message(&#39;【%s】进入了聊天室&#39; % self.request.remote_ip)# 重写on_message方法&#xff0c;当聊天消息有更新时自动触发的函数
def on_message(self, message):# 将在线用户发送的消息通过服务器转发给所有的在线用户
for user in self.online_users:user.write_message(&#39;%s:%s&#39; % (self.request.remote_ip, message))# 重写on_close方法&#xff0c;当有用户离开时自动触发的函数
def on_close(self):# 先将用户从列表中移除
self.online_users.remove(self)# 将该用户离开的消息发送给所有在线的用户
for user in self.online_users:user.write_message(&#39;【%s】离开了聊天室~&#39; % self.request.remote_ip)def check_origin(self, origin):return True
# 程序运行入口
if __name__&#61;&#61;&#39;__main__&#39;:import osBASE_DIR&#61;os.path.dirname(__file__)app&#61;Application([(r&#39;/&#39;,IndexHandler),(r&#39;/login&#39;,LoginHandler),(r&#39;/chat&#39;,ChatHandler),],template_path&#61;os.path.join(BASE_DIR,&#39;templates&#39;),static_path&#61;os.path.join(BASE_DIR,&#39;static&#39;),debug&#61;True,login_url&#61;&#39;/login&#39;,COOKIE_secret&#61;&#39;CPFL2FJOTQGzR/8DXZEyfAjxS9hSTk0Bs0f/A12RMnwI8UvYUk5NAbNH/wNdkTJ8&#39;)server&#61;HTTPServer(app)server.listen(8000)IOLoop.current().start()