应用场景

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. 【BZOJ1087】【SCOI2005】互不侵犯(状态压缩,动态规划)

    题面 这种傻逼题懒得粘贴了... 题解 傻逼题 \(f[i][j][k]\)表示当前第\(i\)列,当前放置状态为\(j\),已经放了\(k\)个 暴力判断状态合法性,暴力判断转移合法性,然后统计答案 ...

  2. 【BZOJ1012】【JSOI2008】最大数(线段树)

    [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当前 ...

  3. CDQ 分治算法模板

    CDQ分治 1.三维偏序问题:三维偏序(陌上花开) #include<bits/stdc++.h> #define RG register #define IL inline #defin ...

  4. 初步谈谈 C# 多线程、异步编程与并发服务器

    多线程与异步编程可以达到避免调用线程异步阻塞作用,但是两者还是有点不同. 多线程与异步编程的异同: 1.线程是cpu 调度资源和分配的基本单位,本质上是进程中的一段并发执行的代码. 2.线程编程的思维 ...

  5. Redis 基础(一)

    Remote Dictionary Server(Redis)是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用ANSI C语言编写.遵守BSD ...

  6. Pythonic

    这个词翻译过来就是 这很python,其产生的目的就是写出更简洁的,没有冗余的python代码. 1.元素交换 a, b = b, a 看到网上有人解释的很好,首先,建立元组的重点不在于括号'()', ...

  7. IntelliJ IDEA 源值1.5已过时,将在未来所有版本中删除

    1. 修改Maven的Settings.xml文件添加如下内容 <profile> <id>jdk-1.8</id> <activation> < ...

  8. Linux源码-等待队列注释

    等待队列 Linux中了等待队列的毒,代码中充斥着等待队列.不信你翻翻代码. 等待队列的唤醒我们这里叫激活.免得和线程唤醒混淆. 数据结构 头结点wait_queue_head_t的结构 struct ...

  9. 剑指Offer-字符流中第一个不重复的字符

    package String; import java.util.LinkedHashMap; import java.util.Map; /** * 字符流中第一个不重复的字符 * 题目描述 * 请 ...

  10. Java8 中 ConcurrentHashMap工作原理的要点分析

    简介: 本文主要介绍Java8中的并发容器ConcurrentHashMap的工作原理,和其它文章不同的是,本文重点分析了不同线程的各类并发操作如get,put,remove之间是如何同步的,以及这些 ...