Tornado websocket应用
应用场景
WebSocket 的特点如下
- 适合服务器主动推送的场景(好友上线,即时聊天信息,火灾警告,股票涨停等)
- 相对于Ajax和Long poll等轮询技术,它更高效,不耗费网络带宽和计算资源
- 它仍然与HTTP完成网络通信
- 不受企业防火墙拦截
通信原理
1.WebSocket 客户端连接报文
- GET /webfin/websocket/ HTTP/1.1
- Host: localhost
- Upgrade: websocket # 建立webSocket链接
- Connection: Upgrade # 建立链接
- Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg== # 密钥
- Origin: <a href="http://localhost/"><code>http://localhost</code></a>:8080
- Sec-WebSocket-Version: 13 # 版本是13
客户端发起的 WebSocket 连接报文类似传统 HTTP 报文,”Upgrade:websocket”参数值表明这是 WebSocket 类型请求,“Sec-WebSocket-Key”是 WebSocket 客户端发送的一个 base64 编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“Error during WebSocket handshake”错误,并关闭连接。
2、服务端收到报文后返回的数据格式类似:
- HTTP/1.1 101 Switching Protocols
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=
“Sec-WebSocket-Accept”的值是服务端采用与客户端一致的密钥计算出来后返回客户端的,“HTTP/1.1 101 Switching Protocols”表示服务端接受 WebSocket 协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的 WebSocket 连接握手成功, 后续就可以进行 TCP 通讯了
服务端编程:
tornadowebsocokt入口函数,需要继承tornado.websocket.WebSocketHandler,并显现open(),on_message(),on_close()函数
还提供了开发者主动操作的websocket函数
WebSocketHandler.write_meassage(message,binary=False) 用于向本链接对应的客户端写消息
WebSocketHandler.close(code=None,reason=None)函数:主动关闭链接,并告知客户端关闭的原因,code参数必须是一个数值,reason必须是一个字符串
实例
- import tornado.web
- import tornado.ioloop
- import tornado.websocket
- from tornado.options import define,options,parse_command_line
- define('port',default=8888,help='run the given port',type=int)
- clients = dict() # 客户端session字典
- class IndexHandler(tornado.web.RequestHandler):
- @tornado.web.asynchronous
- def get(self):
- self.render('index.html')
- class MyWebSocketHandler(tornado.websocket.WebSocketHandler):
- def open(self, *args): # 有新连接时被调用
- self.id = self.get_argument('Id')
- self.stream.set_nodelay(True)
- clients[self.id]={"id":self.id,"object":self} # 保存session到clients字典中
- def on_message(self, message): # 收到消息时被调用
- print("client %s received a message : %s" % (self.id,message))
- def on_close(self): # 关闭链接时被调用
- if self.id in clients:
- del clients[self.id]
- print("client %s is closed" % (self.id))
- def check_origin(self, origin):
- return True
- app = tornado.web.Application([(r'/', IndexHandler), (r'/websocket', MyWebSocketHandler), ])
- import threading
- import time
- # 启动单独的线程运行此函数,每隔1秒向所有客户端推送当前时间
- def sendTime():
- import datetime
- while True:
- for key in clients.keys():
- msg = str(datetime.datetime.now())
- clients[key]['object'].write_message(msg) # 通过WebSocketHandler.write_meassage函数推送时间消息
- print("write to client %s : %s" % (key,msg))
- time.sleep(1)
- if __name__ == '__main__':
- threading.Thread(target=sendTime).start() # 启动推送时间线程
- parse_command_line()
- app.listen(options.port)
- tornado.ioloop.IOLoop.instance().start() # 挂起运行
客户端编程
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <a href="javascript:WebSocketTest()">run websocket</a>
- <div id="messages" style="height: 200px;background: black;color: #e0e0e0;"></div>
- <script type="text/javascript">
- var messageContainer = document.getElementById('messages');
- function WebSocketTest() {
- if ("WebSocket" in window){
- messageContainer.innerHTML = '你的浏览器支持websocket';
- var ws = new WebSocket('ws://localhost:8888/websocket?Id=12345');
- ws.onopen = function () {
- ws.send("message to send");
- };
- ws.onmessage = function (evt) {
- var received_msg = evt.data;
- messageContainer.innerHTML = messageContainer.innerHTML+"<br/>message is received:"+received_msg;
- };
- ws.onclose = function () {
- messageContainer.innerHTML = messageContainer.innerHTML+"<br/>链接已经关闭";
- };
- } else {
- messageContainer.innerHTML = '你的浏览器不支持websocket';
- }
- }
- </script>
- </body>
- </html>
Tornado websocket应用的更多相关文章
- python tornado websocket 实时日志展示
一.主题:实时展示服务器端动态生成的日志文件 二.流程: 1. 客户端浏览器与服务器建立websocket 链接,服务器挂起保存链接实例,等待新内容触发返回动作 2. 日志服务器脚本循环去发现新内容, ...
- python tornado websocket 多聊天室(返回消息给部分连接者)
python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端! chatHome.py // 服务器端, 渲染主页 --> 聊天室建立web ...
- [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 ...
随机推荐
- 爬虫抓包工具Fiddle设置
安装证书(用于https)
- 又把JDK改回JDK1.8的过程
我已经在崩溃的边缘. 先在控制面板卸载9.0.4,非常好,卸的干干净净的. 然后继续卸载9.0.1,也很好,卸的很干净. 命令行: 安装JDK1.8 装完了,去配环境变量: 4个环境变量都配齐了. J ...
- [BZOJ1503] [NOI2004] 郁闷的出纳员 (treap)
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...
- [BZOJ1207] [HNOI2004] 打鼹鼠 (dp)
Description 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探 ...
- 对html进行截图并保存为本地图片
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JAVA通过COM接口操作PPT
一. 背景说明 在Eclipse环境下,开发JAVA代码操作PPT,支持对PPT模板的修改.包括修改文本标签.图表.表格.满足大多数软件生成PPT报告的要求,即先收工创建好模板,在程序中修改模板数据. ...
- XAMPP搭建PHP
在学习一些前后端交互时,经常会有跟PHP作为后端(服务器)的交互,不能将php文件放在本地进行请求,必须将PHP运行在Apache环境中.但是对一些新手来说,学习搭建一个Apache环境也并非易事,所 ...
- Linux tar包安装Nginx-1.7.6 (yum方式安装依赖)
1.首先安装依赖包(依赖包有点多,我们采用yum的方式来安装) yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel ...
- Unity3d底层数据传递分析
WeTest 导读 这篇文章主要分析了在Mono框架下,非托管堆.运行时.托管堆如何关联,以及通过哪些方式调用.内存方面,介绍了什么是封送,以及类和结构体的关系和区别. 一.托管交互(Interop) ...
- JavaScript:方法&对象大全
方法 方法的原型链 <html> <head> <title></title> </head> <script type=" ...