HTML5 websocket

概念

概念 :在HTTP客户端与服务端之间建立持久连接的HTML5的标准技术。
实现 :浏览器与服务器的全双工通信(full-duplex)。
适用场景 : 服务器主动向客户端发送消息

传统实现方式 :Ajax 、Long poll 等动态客户端技术 均采用轮询技术实现,耗费网络带宽,计算资源

WebSocket 通信原理

浏览器端请求

# 客户端发送HTTP Request 告诉服务器建立一个 websocket长链接通道
# 请求头 header中在原基础上增加如下

Connection:Upgrade
sec-WebSocket-Key:uRovscZjNol/umbT5uKmw==   # 密钥为 uRovscZjNol/umbT5uKmw== 
Upgrade:websocket
sec-WwbSocket-Version:13	# 版本号 13

服务器端回复

Connection:Upgrade
Upgrade:websocket
# 对客户端端发送过来的密钥进行加密返回,以便客户端确认服务器正常
sec-WebSocket-Accept:rLHCkw/SKs09GAH/ZSFhBATDKrU==

服务器端基本方法

"""
tornado 定义了tornado.socket.WebSocketHandler类用于处理WebSocket链接请求
开发者应该集成该类,并实现其中的open()、on_message()、on_close() 函数
"""
WebSocketHandler.open()   # 在一个新的WebSocket 建立连接时,框架调用此函数
WebSocketHandler.on_message()   # 建立长连接后,当收到客户端的请求时,框架调用此函数,解析收到消息,并作出应答
WebSocketHandler.on_close()   # 关闭连接时,执行此函数,可以可以通过self.close_code\self.close_reason 查询关闭原因

WebSocketHandler.write_message(message,binary = False )  # 向连接的客户端写消息
# code、reason 用于告诉客户端被关闭的原因,参数code为一个数值,而 reason 为一个字符串
WebSocketHandler.close(code = None,reason = None)  # 主动关闭WebSocket链接、

服务器端编程

import tornado.ioloop
import tornado.web
import tornado.websocket

from tornado.options import define,options,parse_command_line

define("port",default=8888,help="run on the given port",type=int)

clients = dict()

class IndexHandler(tornado.web.RequestHandler):
	@tornado.web.asynchronous
	def get(self):
		# index 中包含 webscket 客户端程序
		self.render("index.html")


# 处理 websocket 请求
class MyWebSocketHandler(tornado.socket.WebSocketHandle):
	# 当有新链接时调用
	def open(self,*args):
		# 获取链接用户提交的Id 
		self.id = self.get_argument("Id")
		self.stream.set_nodelay(True)
		# 保存 session 到 clients 字典中
		clients[self.id] = {"id":self.id,"object":self}
	
	# 接收到消息时被调用
	def on_message(self,message):
		print("Client %s received a message: %s"%(self.id,message))
	
	# 关闭链接时被调用
	def on_close(self):
		if self.id in clients:
			# 将 websocket 从 clients 中删除
			del clients[self.id]
			print("Client %s is closed"%(self.id))
			
	def check_origin(slef,origin):
		return True



app = tornado.web.Application([
	(r'/',IndexHandler),
	(r'/websocket',MyWebSocketHandler),
	])



import threading
import time

# 单线程运行函数,每秒向客户端发送推送当前时间
def sendTime():
	import datetime
	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)


if __name__ =='__main__':
	# 两个线程、一个发送时间、一个接口监听
	threading.Thread(target= sendTime).start()		# 启动推送线程
	parse_command_line()
	app.listen(options.port)
	tornado.ioloop.IOLoop.instance().start()		# 挂起运行

客户端编程

浏览器基本方法

"""
主流的浏览器的Web客户端编程语言 JavaScript 已经支持 WebSocket的客户端编程
客户端 JavaScript 可以通过如下代码初始化 WebSocket 对象
"""
var Socket = new WebSocket(url)   # 传入服务器的URL地址

WebSocket.onopen		# 此事件发生在WebSocket 链接建立时
WebSocket.onmessage		# 此事件发生在收到来自服务器的消息时
WebSocket.onreeor		# 此事件发生在通信过程中有任何错误时
WebSocket.onclose		# 此事件发生在与服务器的链接关闭时
WebSocket.send(data)		# 向服务器发送消息
WebSocket.close()		# 主动关闭现有链接
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值