应用场景

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应用的更多相关文章

  1. python tornado websocket 实时日志展示

    一.主题:实时展示服务器端动态生成的日志文件 二.流程: 1. 客户端浏览器与服务器建立websocket 链接,服务器挂起保存链接实例,等待新内容触发返回动作 2. 日志服务器脚本循环去发现新内容, ...

  2. python tornado websocket 多聊天室(返回消息给部分连接者)

    python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端! chatHome.py // 服务器端, 渲染主页 --> 聊天室建立web ...

  3. [tornado]websocket 最简单demo

    想法 前两天想看看django 长轮询或者是websocket的方案,发现都不太好使. tornado很适合做这个工作,于是找了些资料,参照了做了个最简单demo,以便备用. 具体的概念就不说了,to ...

  4. tornado websocket聊天室

    1.app.py #!/usr/bin/env python # -*- coding:utf-8 -*- import uuid import json import tornado.ioloop ...

  5. tornado WebSocket详解

    1.什么是WebSocketwebsocket和长轮询的区别是客户端和服务器之间是持久连接的双向通信.协议使用ws://URL格式,但它在是在标准HTTP上实现的. 2.tornado的WebSock ...

  6. nginx,tornado,websocket,supervisord配置成型

    因为要上生产环境,所以配置还是专业一些比较好. nginx.conf upstream websocket_host { server 127.0.0.1:9527; } location /ws_l ...

  7. Tornado WebSocket简单聊天

    Tornado实现了对socket的封装:tornado.web.RequestHandler 工程目录: 1.主程序 manage.py import tornado.web import torn ...

  8. tornado+websocket+mongodb实现在线视屏文字聊天

    最近学了tornado和mongo,所以结合websocket 实现一个聊天功能,从而加深一下相关知识点的印象 1.websocket概览 webscoket是一种全双工通信模式的协议,客户端连接服务 ...

  9. websocket 与 tornado 的结合

    对于socket是不陌生的,但是对于websocket我却是陌生的,不同于https,在网页中使用websocket可以同样起到ajax的作用,默默发送数据... 在script中: ws = new ...

随机推荐

  1. 【NOIP2014】解方程(枚举)

    题面 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, m ] 内的整数解(n 和m 均为正整数) 输入格式 输入共n + 2 行. 第一行包含2 个整数 ...

  2. 论文笔记(2):Deep Crisp Boundaries: From Boundaries to Higher-level Tasks

    ---------------------------------------------------------------------------------------------------- ...

  3. (2)Deep Learning之线性单元和梯度下降

    往期回顾 在上一篇文章中,我们已经学会了编写一个简单的感知器,并用它来实现一个线性分类器.你应该还记得用来训练感知器的『感知器规则』.然而,我们并没有关心这个规则是怎么得到的.本文通过介绍另外一种『感 ...

  4. Python 2.7版本与3.6的不同

    初学python,暂时就记一点. 1.print 2.7:print "123" #正常 3.6:print "123" #报错,正常应该是print在输出任何 ...

  5. 关于C++ const 的全面总结《转》

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...

  6. python数据类型——数字类型

    Python3 中有六个标准的数据类型: Number(数字) String(字符串) List(列表) Tuple(元组) Sets(集合) Dictionary(字典) 数字类型(Number): ...

  7. HashMap中的resize以及死链的情况

    之前我已经写过关于HashMap的内容了:http://www.cnblogs.com/wang-meng/p/7545725.html 我们都知道HashMap是线程不安全的, 如果多线程来访问会有 ...

  8. Appserv(Apache) 配置ssl证书

    一:打开httpd.conf文件,移除注释的行: Include conf/extra/httpd-ahssl.conf LoadModule ssl_module modules/mod_ssl.s ...

  9. Linux IPMI 配置管理.md

    DELL 服务器 user id 范围:1-16 可以修改用户名和密码 不允许用户名重复 当设置一个已存在的用户名时,无论user id在前或在后,修改密码会将该项用户名设置为空,enable会恢复成 ...

  10. H5页面基于接口实现数据交互

    对于现在APP开发来说,目前流行的两个方式是原生和H5.就如同之前业界程序猿争论的BS和CS之争一样,业界对于H5和原生也有不小的争论.对于前者的争论在于PC端,后者在于移动端上体现. 那一个APP适 ...