Websocket
WebSocket实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端可以主动向客户端发送数据。
传统的HTTP协议是无状态的,种客户端是主动方,服务端是被动方的;对于涉及实时信息的Web应用带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应用。在之前有两种办法解决这个问题
轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动。这种方法会导致过多不必要的请求,浪费流量和服务器资源。
Comet技术又可以分为长轮询和流技术;长轮询改进了上述的轮询技术,减小了无用的请求。它会为某些数据设定过期时间,当数据过期后才会向服务端发送请求;这种机制适合数据的改动不是特别频繁的情况。流技术通常是指客户端使用一个隐藏的窗口与服务端建立一个HTTP长连接,服务端会不断更新连接状态以保持HTTP长连接存活;这样的话,服务端就可以通过这条长连接主动将数据发送给客户端;流技术在大并发环境下,可能会考验到服务端的性能。
WebSocket真正实现了Web的实时通信,使B/S模式具备了C/S模式的实时通信能力
WebSocket的工作流程是这样的:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过 TCP连接传输数据。因为WebSocket连接本质上是TCP连接,不需要每次传输都带上重复的头部数据,所以它的数据传输量比轮询和Comet技术小了很多
Websocket在建立连接之前有一个Handshake(Opening Handshake)过程,在关闭连接前也有一个Handshake(Closing Handshake)过程,建立连接之后,双方即可双向通信
HTML的Websocket
- 初始化websocket
var ws = new WebSocket(url, [protocol] );
url:指定连接的websocket
protocol:可接受的子协议
响应事件
当
ws套接字初始化成功之后,我们可以通过定义回调函数在某些事件触发时执行,以下是常见响应事件
- 当
ws连接建立时触发
ws.onopen = function(){
// 连接开启
}
- 当
ws连接接收到数据时触发
ws.onmessage = function(evt){
// evt.data即是接收到的数据对象
}
- 当
ws连接发生通信错误时触发
ws.onerror = function(){
// 连接出错
}
- 当连接关闭时触发
ws.onclose = function(){
// 连接关闭
}
初次之外,还可以通过一些方法函数进行数据的传输或连接的关闭
方法
- 通过
ws连接发送数据
ws.send(str)
- 关闭连接
ws.close()
示例
var ws = new WebSocket('ws://127.0.0.1:3000')
ws.onopen = function(){
console.log('连接建立')
}
ws.onmessage = function(ev){
console.log('server:',ev.data)
}
ws.onerror = function(){
console.log('连接建立')
ws.close()
}
ws.onclose = function(){
console.log('连接关闭')
ws.close()
}
Django的Websocket
dwebsocket是一个在django用来实现websocket服务端的三方模块,使用上手非常简单,安装方式如下
pip install dwebsocket
git地址
方法
在后台中,通过该三方模块可以让我们在
django的视图中实现对于websocket的操作
首先是两个基本的装饰器,用来限定过滤
websocket的连接
dwebsocket.accept_websocket
允许
http与websocket连接
dwebsocket.require_websocke
只允许
websocket连接
除去两种装饰器方法进行过滤判断,还可以通过在视图函数中的
request进行websocket的判断
request.is_websocket
如果是个
websocket请求返回True,如果是个普通的http请求返回False可以用这个方法区分普通连接与
websocket
request.websocket
在一个
websocket请求建立之后,这个请求将会有一个websocket属性,用来给客户端提供一个简单的api通讯,如果request.is_websocket()是False,这个属性将是None
request.websocket.wait
接收客户端发来的一条消息;如果在收到消息或客户端关闭连接之前,它不会有任何返回,只会返回None
request.websocket.read
如果从客户端接收到新消息,
read函数返回这条消息;如果没有新消息,则返回None这是一个替代
wait的非阻塞读取数据的方法
request.websocket.count_messages()
返回消息队列数量
request.websocket.has_messages()
如果有新消息返回
True,否则返回False
request.websocket.send(message)
向客户端发送消息
requqest.websocket.__iter__