应用场景

WebSocket 的特点如下

  • 适合服务器主动推送的场景(好友上线,即时聊天信息,火灾警告,股票涨停等)
  • 相对于Ajax和Long poll等轮询技术,它更高效,不耗费网络带宽和计算资源
  • 它仍然与HTTP完成网络通信
  • 不受企业防火墙拦截

通信原理

1.WebSocket 客户端连接报文
  1. GET /webfin/websocket/ HTTP/1.1
  2. Host: localhost
  3. Upgrade: websocket # 建立webSocket链接
  4. Connection: Upgrade # 建立链接
  5. Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg== # 密钥
  6. Origin: <a href="http://localhost/"><code>http://localhost</code></a>:8080
  7. Sec-WebSocket-Version: 13 # 版本是13

客户端发起的 WebSocket 连接报文类似传统 HTTP 报文,”Upgrade:websocket”参数值表明这是 WebSocket 类型请求,“Sec-WebSocket-Key”是 WebSocket 客户端发送的一个 base64 编码的密文,要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept”应答,否则客户端会抛出“Error during WebSocket handshake”错误,并关闭连接。

2、服务端收到报文后返回的数据格式类似:

  1. HTTP/1.1 101 Switching Protocols
  2. Upgrade: websocket
  3. Connection: Upgrade
  4. 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必须是一个字符串

实例

  1. import tornado.web
  2. import tornado.ioloop
  3. import tornado.websocket
  4.  
  5. from tornado.options import define,options,parse_command_line
  6.  
  7. define('port',default=8888,help='run the given port',type=int)
  8.  
  9. clients = dict() # 客户端session字典
  10.  
  11. class IndexHandler(tornado.web.RequestHandler):
  12. @tornado.web.asynchronous
  13. def get(self):
  14. self.render('index.html')
  15.  
  16. class MyWebSocketHandler(tornado.websocket.WebSocketHandler):
  17. def open(self, *args): # 有新连接时被调用
  18. self.id = self.get_argument('Id')
  19. self.stream.set_nodelay(True)
  20. clients[self.id]={"id":self.id,"object":self} # 保存session到clients字典中
  21.  
  22. def on_message(self, message): # 收到消息时被调用
  23. print("client %s received a message : %s" % (self.id,message))
  24.  
  25. def on_close(self): # 关闭链接时被调用
  26. if self.id in clients:
  27. del clients[self.id]
  28. print("client %s is closed" % (self.id))
  29.  
  30. def check_origin(self, origin):
  31. return True
  32.  
  33. app = tornado.web.Application([(r'/', IndexHandler), (r'/websocket', MyWebSocketHandler), ])
  34.  
  35. import threading
  36. import time
  37.  
  38. # 启动单独的线程运行此函数,每隔1秒向所有客户端推送当前时间
  39. def sendTime():
  40. import datetime
  41. while True:
  42. for key in clients.keys():
  43. msg = str(datetime.datetime.now())
  44. clients[key]['object'].write_message(msg) # 通过WebSocketHandler.write_meassage函数推送时间消息
  45. print("write to client %s : %s" % (key,msg))
  46. time.sleep(1)
  47.  
  48. if __name__ == '__main__':
  49. threading.Thread(target=sendTime).start() # 启动推送时间线程
  50. parse_command_line()
  51. app.listen(options.port)
  52. tornado.ioloop.IOLoop.instance().start() # 挂起运行

客户端编程

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <a href="javascript:WebSocketTest()">run websocket</a>
  9. <div id="messages" style="height: 200px;background: black;color: #e0e0e0;"></div>
  10.  
  11. <script type="text/javascript">
  12. var messageContainer = document.getElementById('messages');
  13. function WebSocketTest() {
  14. if ("WebSocket" in window){
  15. messageContainer.innerHTML = '你的浏览器支持websocket';
  16. var ws = new WebSocket('ws://localhost:8888/websocket?Id=12345');
  17. ws.onopen = function () {
  18. ws.send("message to send");
  19. };
  20. ws.onmessage = function (evt) {
  21. var received_msg = evt.data;
  22. messageContainer.innerHTML = messageContainer.innerHTML+"<br/>message is received:"+received_msg;
  23. };
  24. ws.onclose = function () {
  25. messageContainer.innerHTML = messageContainer.innerHTML+"<br/>链接已经关闭";
  26. };
  27.  
  28. } else {
  29. messageContainer.innerHTML = '你的浏览器不支持websocket';
  30. }
  31. }
  32. </script>
  33. </body>
  34. </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. 爬虫抓包工具Fiddle设置

    安装证书(用于https)

  2. 又把JDK改回JDK1.8的过程

    我已经在崩溃的边缘. 先在控制面板卸载9.0.4,非常好,卸的干干净净的. 然后继续卸载9.0.1,也很好,卸的很干净. 命令行: 安装JDK1.8 装完了,去配环境变量: 4个环境变量都配齐了. J ...

  3. [BZOJ1503] [NOI2004] 郁闷的出纳员 (treap)

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

  4. [BZOJ1207] [HNOI2004] 打鼹鼠 (dp)

    Description 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探 ...

  5. 对html进行截图并保存为本地图片

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. JAVA通过COM接口操作PPT

    一. 背景说明 在Eclipse环境下,开发JAVA代码操作PPT,支持对PPT模板的修改.包括修改文本标签.图表.表格.满足大多数软件生成PPT报告的要求,即先收工创建好模板,在程序中修改模板数据. ...

  7. XAMPP搭建PHP

    在学习一些前后端交互时,经常会有跟PHP作为后端(服务器)的交互,不能将php文件放在本地进行请求,必须将PHP运行在Apache环境中.但是对一些新手来说,学习搭建一个Apache环境也并非易事,所 ...

  8. Linux tar包安装Nginx-1.7.6 (yum方式安装依赖)

    1.首先安装依赖包(依赖包有点多,我们采用yum的方式来安装) yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel ...

  9. Unity3d底层数据传递分析

    WeTest 导读 这篇文章主要分析了在Mono框架下,非托管堆.运行时.托管堆如何关联,以及通过哪些方式调用.内存方面,介绍了什么是封送,以及类和结构体的关系和区别. 一.托管交互(Interop) ...

  10. JavaScript:方法&对象大全

    方法 方法的原型链 <html> <head> <title></title> </head> <script type=" ...