tornado-websocket
WebSockets 允许浏览器和服务器之间进行 双向通信
server端:
class WebSocketHandler(WebBaseHandler):
''' websocket '''
users = {} # {u'liubei': <handlers.message.message_handler.WebSocketHandler object at 0xb620b34c>,
# u'rock': <handlers.message.message_handler.WebSocketHandler object at 0xb61794ec>} # ------------------提高部分 开始------------------
# 提高部分只是细分发送信息的对象,不是很重要。完成提高部分结束后的 open,on_message, on_close即可。
@classmethod
def send_system_message(cls, self, content, send_type):
"""
:param self: 继承过websocket的base类的实例化对象,主要是self初始化了操作redis,mysql以及user对象的属性
:param content: 储存进redis的list data
:param send_type: 发送的类型(发给boss,ceo,员工...),由前端传过来
:return: 系统消息,发送给每个人
"""
target = 'system'
redis_msg = cls.dict_to_json(self, content, send_type, target)
self.conn.rpush('message:%s' % send_type, redis_msg) for f, v in WebSocketHandler.users.items():
v.write_message(redis_msg) @classmethod
def dict_to_json(cls, self, content, send_type, target):
"""
:param self: 继承过websocket的base类的实例化对象,主要是self初始化了操作redis,mysql以及user对象的属性
:param content: 储存进redis的list data
:param send_type: 发送的类型(发给boss,ceo,员工...),由前端传过来
:param target: 相当与用来区分缓存key的名字,比如 key_name="cache_list:%s"%target1, ...取对应分类的历史数据
:return:
"""
msg = {
"content": content,
"send_type": send_type,
"sender": self.current_user.name,
"target": target,
"datetime": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
return tornado.escape.json_encode(msg) @classmethod
def send_role_message(cls, self, content, send_type, roleid):
"""
:param self:
:param content:
:param send_type:
:param roleid: 通过角色id,反查出属于该角色id的用户
:return: 发送信息给 该角色的所用用户
"""
role = Role.by_id(roleid)
redis_msg = cls.dict_to_json(self, content, send_type, role.name)
self.conn.rpush('message:%s' % send_type, redis_msg)
role_users = role.users # [zhangsan, lishi , wangwu] [zhangsan, lishi]
for user in role_users:
if WebSocketHandler.users.get(user.name, None) is not None: # user.name ['rock':self]
WebSocketHandler.users[user.name].write_message(redis_msg)
else:
# self.conn.lpush("ws:role_off_line",message)
pass @classmethod
def send_user_message(cls, self, content, send_type, user):
"""
:param self:
:param content:
:param send_type:
:param user: 发送的对象
:return: 发送信息给改用户 user
"""
redis_msg = cls.dict_to_json(self, content, send_type, user) self.conn.rpush('message:%s' % send_type, redis_msg)
self.conn.rpush('message:%s' % user, redis_msg) # 为了显示未读消息条数 if cls.users.get(user, None) is not None:
cls.users[user].write_message(redis_msg)
else:
# self.conn.lpush("ws:user_off_line",message)
pass # ------------------提高部分 结束------------------ def open(self):
'''
有用户进来后,存储该用户 {usernaem: self} self是每个登录用户的实例化类
(用该实例化对象发送是那个消息)
'''
WebSocketHandler.users[self.current_user.name] = self
pass def on_message(self, message): # 改方法获取消息,前端通过 ws对象.send(msg)发送
# print message # {"content_html":"聊天框输入的内容"} json
# {"content_html":"afaf<img src=\"/static/images/face/nm_thumb.gif\" title=\"[怒骂]\">"}
msg = tornado.escape.json_decode(message) # 解码 json字符串 --> 字符串
msg.update({
"name": self.current_user.name,
"datetime": datetime.now().strftime("%Y-%m-%d %H-%M-%S")
}) message = tornado.escape.json_encode(msg) # 转成json self.conn.rpush('message:list', message) # 存储消息为了显示历史消息 # self.write_message(msg) # 就算不转成json,write_message也能自己编码 # WebSocketHandler.users['liubei'].write_message(message) # 这是将不管谁的message只发给用户liubei for f, v in WebSocketHandler.users.items():
v.write_message(message) def on_close(self):
pass
前端:和后端一样,都需要完成open,on_message,on_close三个方法
<script type="text/javascript">
$(document).ready(function(){
//与服务器建立websocket链接请求
var url="ws://" + location.host + "/ws"; //是open, on_message, on_close所在类映射的路由。是通过ws协议,而不是http
var ws= new WebSocket(url);//在浏览器打开一个socket 服务器打开一个socket ws.onopen=function(){
$('#status').text('已经建立链接');
var tishi = $('.tishi');
var name = tishi.attr('username');
tishi.append("<div>"+name+"加入了聊天室...</div>")
}; ws.onclose=function () {
$('#status').text('已经断开链接')
}; //当收到服务器向浏览器推送消息时调用这个函数
ws.onmessage=function(event){ message = JSON.parse(event.data);
if(message.content_html){
append(message);
}else{
append_m(message);
}
}; //点出头像函数
$('.t_gif').click(function(){
$('.t_box').toggle(300);
}); // 点击表情时把点击的表情添加到文本框中
$('#q_ul li').click(function(){
var img = $(this).find("img").clone();
$(".t_input").append(img);
$(".t_input").focus();
}); // 点击发布按钮时调用wsbsocket.send()函数向服务器发送数据
$(".t_btn").click(function(){
var content_html = $('.t_input').html();
console.log(content_html);
var massage = {
"content_html":content_html
};
ws.send(JSON.stringify(massage)); }); // 动态添加发布消息的函数
function append(msg){
//向留言中添加消息
$(".t_all").prepend(function(n){
var content_html='';
var useravatar='';
var datetime1='';
if(msg){
content_html = msg.content_html;
var useravatar = 'defaut_avatar.jpeg';
datetime1 = msg.datetime;
}
return "<div class='t_list animated bounceIn'>"+
"<div class='t_header'>"+
"<img src='/static/images/useravatars/" + useravatar +"' alt='' width='64' height='64' />"+
"</div>"+
"<div class='t_icon'></div>"+
"<div class='t_msg'>"+"<p style='font-size:8px;'>"+
"<a class='name' href='#'>" +msg.name+ " </a>"+
datetime1+"</p>"+content_html+"</div>"+
"<div class='clear'></div>"+
"</div>"
});
$('.t_box').hide(400);
$('.t_input').text('');
$('.t_input').focus();
} // 发布系统消息的函数
function append_m(msg){
$(".system_all").html('');
var target = "";
if(msg.target == "system"){
target = "全体人员"
}else{
target = msg.target
}
var messages = "消息内容:"+msg.content+
" 消息类型:"+
msg.send_type+" 发送者:"+
msg.sender +" 接收者:"+
target+" 时间:"+
msg.datetime;
$(".system_all").html(messages);
}
})
</script>
参考中文文档:https://tornado-zh.readthedocs.io/zh/latest/websocket
tornado-websocket的更多相关文章
- python tornado websocket 实时日志展示
一.主题:实时展示服务器端动态生成的日志文件 二.流程: 1. 客户端浏览器与服务器建立websocket 链接,服务器挂起保存链接实例,等待新内容触发返回动作 2. 日志服务器脚本循环去发现新内容, ...
- python tornado websocket 多聊天室(返回消息给部分连接者)
python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端! chatHome.py // 服务器端, 渲染主页 --> 聊天室建立web ...
- Tornado websocket应用
应用场景 WebSocket 的特点如下 适合服务器主动推送的场景(好友上线,即时聊天信息,火灾警告,股票涨停等) 相对于Ajax和Long poll等轮询技术,它更高效,不耗费网络带宽和计算资源 它 ...
- [tornado]websocket 最简单demo
想法 前两天想看看django 长轮询或者是websocket的方案,发现都不太好使. tornado很适合做这个工作,于是找了些资料,参照了做了个最简单demo,以便备用. 具体的概念就不说了,to ...
- tornado websocket聊天室
1.app.py #!/usr/bin/env python # -*- coding:utf-8 -*- import uuid import json import tornado.ioloop ...
- tornado WebSocket详解
1.什么是WebSocketwebsocket和长轮询的区别是客户端和服务器之间是持久连接的双向通信.协议使用ws://URL格式,但它在是在标准HTTP上实现的. 2.tornado的WebSock ...
- nginx,tornado,websocket,supervisord配置成型
因为要上生产环境,所以配置还是专业一些比较好. nginx.conf upstream websocket_host { server 127.0.0.1:9527; } location /ws_l ...
- Tornado WebSocket简单聊天
Tornado实现了对socket的封装:tornado.web.RequestHandler 工程目录: 1.主程序 manage.py import tornado.web import torn ...
- tornado+websocket+mongodb实现在线视屏文字聊天
最近学了tornado和mongo,所以结合websocket 实现一个聊天功能,从而加深一下相关知识点的印象 1.websocket概览 webscoket是一种全双工通信模式的协议,客户端连接服务 ...
- websocket 与 tornado 的结合
对于socket是不陌生的,但是对于websocket我却是陌生的,不同于https,在网页中使用websocket可以同样起到ajax的作用,默默发送数据... 在script中: ws = new ...
随机推荐
- Hanlp在java中文分词中的使用介绍
项目结构 该项目中,.jar和data文件夹和.properties需要从官网/github下载,data文件夹下载 项目配置 修改hanlp.properties: 1 #/Test/src/han ...
- Video Timing Controller v6.1软件调试记录
Video Timing Controller v6.1软件调试记录 GUI配置: . case XVTC_VMODE_PAL: //576i@50 { TimingPtr->Interlace ...
- excel技巧--批量生成工资条
要想生成如上图的工资条,快速的方法如下: 1.在工资表右侧建立一升序数字列,完成后再复制该列,重复粘贴一次在该列底部.2.对该表排序:“开始”-->“排序和筛选”-->自定义排序.在对话框 ...
- java.lang.OutOfMemoryError: Java heap space解决方法 (有问题咨询加微信)
支付宝扫码领取最高99元红包,到店支付15天,双十二瓜分15亿,打开支付宝首页搜“555176706”领红包,领到大红包的小伙伴赶紧使用哦! //首先检查程序有没有限入死循环 这个问题主要还是由这个问 ...
- Python3中Urllib库基本使用
什么是Urllib? Python内置的HTTP请求库 urllib.request 请求模块 urllib.error 异常处理模块 urllib.par ...
- ADO.NET目录汇总1
1.引用命名空间: using System.Data; using System.Data.SqlClient;[访问SQL Server定义的类] 2.连接字符串 string connectio ...
- NIO基本操作
NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题 NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器) Channel(通道) ...
- mac下 python3 安装--有说明原电脑安装的文件在哪里
https://www.cnblogs.com/meng1314-shuai/p/9031686.html 前言:mac系统自带python,不过以当前mac系统的最新版本为例,自带的python版本 ...
- ngx_lua_waf
Web应用防护系统Web Application Firewall,简称WAF.针对HTTP/HTTPS的安全策略专门为Web应用提供保护的产品. OpenResty是一个基于 Nginx 与 Lua ...
- C语言强化——文件
文件操作 fopen与fclose fread与fwrite fseek fputs与fgets fscanf与fprintf fopen与fclose #include<stdio.h> ...