Tornado编程-WebSocket原理及代码示例

管理员 python来源:qmailerTornado编程-WebSocket原理及代码示例已关闭评论12,0743字数 4031阅读13分26秒阅读模式

一. WebSocket协议

WebSocket 协议本质上是一个基于 TCP 的协议。

为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/

由于这个规范目前还是处于草案阶段,版本的变化比较快,通常采用 draft-hixie-thewebsocketprotocol-76 版本来描述 WebSocket 协议,详情可访问 http://dev.w3.org/html5/websockets/。文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/

二. Firefox的WebSocket实现

1. 请求

GET /send HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Cache-Control: no-cache
Connection: keep-alive, Upgrade
Host: 127.0.0.1:8200
Origin: http://127.0.0.1:8200
Pragma: no-cache
Sec-WebSocket-Key: KOySRTQgzqImO5s57OkTPA==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0

2. 应答文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Sec-WebSocket-Accept: rr+f1d2NTgfAJeQ8t6/kzHli9ao=
Upgrade: websocket

三. 基于Tornado3.1的WebSocket编程实现

1.HTML示例
注:基于jQuery、Bootstrap,同时将websocket.html保存在websocket.py同级的template目录下文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/

<html>
<head> 
<link href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link href="http://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap-theme.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script> 
function send() { 
    var ws = new WebSocket("ws://127.0.0.1:8200/send"); 
 
    var data = {
        input:$("#input_data").val(),
    };
 
    $("#message").empty();
    ws.onopen = function() {
        ws.send(JSON.stringify(data)); 
    };
 
    $("#message").append('<div class="panel-body"><p>');
    ws.onmessage = function(event) { 
        $("#message").append(JSON.parse(event.data).input + "<br>");
    };
 
    ws.onclose = function(event) {
        $("#message").append('</p></div>');
    };
}
</script>
</head>
<body>
  <div id="test">
  <form class="form-horizontal" role="form">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h5 class="panel-title">>>输入</h5>
      </div>
      <div class="panel-body">
        <div class="form-group">
          <div class="col-md-8">
            <input type="text" class="form-control" id="input_data" value="">
          </div>
        </div>
        <div class="form-group">
          <div class="col-md-8">
            <button type="submit" class="btn btn-success" id="input_btn" onclick="send();">发送</button>
          </div>
        </div>
      </div>
    </div>
  </form>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h5 class="panel-title">>> 输出</h5>
    </div>
    <div class="panel-body">
      <div id="message"></div>
    </div>
  </div>
</body>
</html>

2.python示例文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/

import os
import sys
import json
import time
import tornado.httpserver
import tornado.web
import tornado.ioloop
from tornado import websocket
 
class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("websocket.html")
 
class SendHandler(websocket.WebSocketHandler):
    clients = set()
 
    def open(self):
        SendHandler.clients.add(self)
        self.write_message(json.dumps({'input': 'connected...'}))
        self.stream.set_nodelay(True)
 
    def on_message(self, message):
        message = json.loads(message)
        self.write_message(json.dumps({'input': 'response...'}))
        i = 0
        while i <= 10:
            i += 1
            self.write_message(json.dumps(message))
            time.sleep(1)
        # 服务器主动关闭
        self.close()
        SendHandler.clients.remove(self)
 
    def on_close(self):
        # 客户端主动关闭
        SendHandler.clients.remove(self)
 
if __name__ == '__main__':
    app = tornado.web.Application(
        handlers=[
            (r"/", IndexHandler),
            (r"/send", SendHandler)
        ],
        debug = False,
        template_path = os.path.join(os.path.dirname(__file__), "template"),
        static_path = os.path.join(os.path.dirname(__file__), "static")
    )
    http_server = tornado.httpserver.HTTPServer(app, xheaders=True)
    http_server.listen(8200)
    tornado.ioloop.IOLoop.instance().start()

 文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/

文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/文章源自运维生存时间-https://www.ttlsa.com/python/tornado-code-websocket-sample/
weinxin
我的微信
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
管理员
  • 版权声明 本文源自 qmailer 整理 发表于 23/10/2016 17:27:46
  • 转载请务必保留本文链接:https://www.ttlsa.com/python/tornado-code-websocket-sample/