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 ...
随机推荐
- Elasticsearch集成HanLP分词器
1.通过git下载分词器代码. 连接如下:https://gitee.com/hualongdata/hanlp-ext hanlp官网如下:http://hanlp.linrunsoft.com/ ...
- MySql 常见错误代码大全 VV2
从机一直1593错误,排查了半天发现是从的配置文件中的server-id没改导致,此低级错误记录下警醒自己 B.1. 服务器错误代码和消息 服务器错误信息来自下述源文件: · 错误消息信息列在shar ...
- 进程池pool
如果有多个进程,同一时间只能有限个给cpu运行 from multiprocessing import Process,Pool import time,os def bar(arg): print( ...
- XE5 Android 开发数据访问server端[转]
建立一个webservices stand-alone vcl application 作为手机访问的服务端 1.new->other->webservices 2.选择 stand-a ...
- qt编程
http://www.zhihu.com/question/20054048 http://www.cnblogs.com/luoshupeng/archive/2011/05/01/2033743. ...
- 黄聪:如何高效率存储微信中的 access_token
众所周知,在微信开发中,获取access_token 的接口每天的调用次数是有限制的,2000次应该是. 不过其实这些完全够用了,除非你不小心写了个循环,在1秒中内用完了. 每个access_toke ...
- vue之v-for
vue.js 的循环渲染是依赖于 v-for 指令,它能够根据 vue 的实例里面的信息,循环遍历所需数据,然后渲染出相应的内容.它可以遍历数组类型以及对象类型的数据,js 里面的数组本身实质上也是对 ...
- vue之v-model
上一篇文章总结了v-bind的用法,我们发现v-bind实现了数据的单向绑定,将vue实例中的数据同元素属性值进行绑定,今天我们将总结vue中的数据双向绑定v-model. v-model实现双向绑定 ...
- Java NIO系列教程(四) Scatter/Gather
Java NIO开始支持scatter/gather,scatter/gather用于描述从Channel(译者注:Channel在中文经常翻译为通道)中读取或者写入到Channel的操作.分散(sc ...
- Linux下统计局域网流量
1:统计10.86.0.0/16网段的内网流量情况 将下面脚本保存成文件traffic-lan.sh(运行后需要等待10秒抓包) tcpdump -nqt src net and dst net ! ...