文章目录
一、什么是websocket?二、基于tornado实现websocket通信1.WebsocketHandler学习1) WebSocketHandler.open()2) WebSocketHandler.on_message(message)3) WebSocketHandler.on_close()4)WebSocketHandler.write_message(message, binary=False)5)WebSocketHandler.close(code=None,reason=None)
2.基于tornado实现服务端给客户端持续推送时间服务端server.py客户端index.html测试以及结果
一、什么是websocket?
websocket是html定义的一种标准的协议, 旨在解决浏览器与服务器之间的全双工通信,比如微信好友上线通知、新闻热点通知等,都可以通过websocket来实现服务器向客户端发送消息。 websocket能够解决Http+HTML在应用中的局限性。
二、基于tornado实现websocket通信
1.WebsocketHandler学习
WebsocketHandler是tornado.web框架下封装的处理websocket通信的类,继承WebsocketHandler类,能实现对Websocket消息的操作,WebsocketHandler的常用函数有:
1) WebSocketHandler.open()
  在一个新的WebSocket链接建立时,Tornado框架会调用此函数。在本函数中,我们可以和在get()、post()等函数中一样用get_argument()函数获取客户端提交的参数,以及用get_secure_cookie/set_secure_cookie操作Cookie等,如下:
self.stream.set_nodelay(True) : 官方解释: set the no-delay flag for this stream, 在一个数据包在发送中,往往会分为很多很小的消息,这就会导致在发送消息是出现200-500ms的延迟,通过设置set_nodelay(True)能够增大TCP连接时增大带宽以达到减小延时的目的,同时我们应该一个websocket连接一建立的时候去调用这个方法。
2) WebSocketHandler.on_message(message)
建立WebSocket链接后,当收到来自客户端的消息时,Tornado框架会调用本函数。通常,这是服务器端WebSocket编程的核心函数,通过解析收到的消息做出相应的处理。
3) WebSocketHandler.on_close()
当WebSocket链接被关闭时,Tornado框架会调用本函数。在本函数中,可以通过访问self.close_code和self.close_reason查询关闭的原因。
4)WebSocketHandler.write_message(message, binary=False)
用于向与本链接相对应的客户端写消息。
5)WebSocketHandler.close(code=None,reason=None)
主动关闭WebSocket链接。其中的code和reason用于告诉客户端链接被关闭的原因。参数code必须是一个数值,而reason是一个字符串。
2.基于tornado实现服务端给客户端持续推送时间
服务端server.py
import tornado
.ioloop
import tornado
.web
import tornado
.websocket
from tornado
import gen
from tornado
.options
import define
, options
, parse_command_line
define
("port", default
=8888, help="run on given port", type=int)
clients
= dict()
class IndexHandler(tornado
.web
.RequestHandler
):
@tornado
.web
.asynchronous
def get(self
):
print("访问系统首页...")
self
.render
("index.html")
class MyWebSocketHandler(tornado
.websocket
.WebSocketHandler
):
def open(self
, *args
, **kwargs
):
self
.id = self
.get_argument
("id")
self
.stream
.set_nodelay
(True)
clients
[self
.id] = {"id": self
.id, "object": self
}
print(clients
)
print("建立连接...")
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
import threading
import time
import datetime
def send_time():
while True:
for key
in clients
.keys
():
msg
= str(datetime
.datetime
.now
())
clients
[key
]["object"].write_message
(msg
)
print("write to client %s:%s" % (key
, msg
))
time
.sleep
(1)
app
= tornado
.web
.Application
([
(r
"/", IndexHandler
),
(r
"/websocket", MyWebSocketHandler
)
])
if __name__
== "__main__":
threading
.Thread
(target
=send_time
).start
()
parse_command_line
()
app
.listen
(options
.port
)
tornado
.ioloop
.IOLoop
.instance
().start
()
客户端index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>系统首页
</title>
</head>
<body>
欢迎您!
<br>
<a href="javascript:WebSocketTest()">启动websocket
</a>
<div id="messages"></div>
</body>
<script type="text/javascript">
var message_editors=document.getElementById("messages")
function WebSocketTest(){
if ("WebSocket" in window){
message_editors.innerHTML="websocket is supported by windows"
var ws=new WebSocket("ws://localhost:8888/websocket?id=12345")
console.log(ws)
alert("启动websocket!")
ws.open=function(){
ws.send("message to send");
}
ws.onmessage=function(evt){
var recevied_msg=evt.data
message_editors.innerHTML=message_editors.innerHTML+"<br/>message is reveived:"+recevied_msg
}
ws.onclose=function(){
message_editors.innerHTML=message_editors.innerHTML+"<br/>connection is closed..."
}
}else{
message_editors.innerHTML="websocket not supported by your brower!"
alert("不支持websockt!")
}
}
</script>
</html>
测试以及结果
访问Localhost:8888, 点击启动websocket,观察控制台和浏览器页面信息 1)控制台打印信息:
2)浏览器接收消息: