websocket是个啥?
webSocket是一种在单个TCP连接上进行全双工通信的协议
webSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯
轮询是几个意思?
轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动。明显地,这种方法会导致过多不必要的请求,浪费流量和服务器资源。总之就是一种low到爆炸的原始作坊水平的技术。
本文通过基于dwebsocket库来将socket嵌入到django服务中,使其服务兼具http协议和socket协议,能够达到实时前后端通信,后端主动推送等功能
安装dwebsocket库
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple dwebsocket
定义视图文件的逻辑views.py
#导入websocket装饰器
from dwebsocket.decorators import accept_websocket
#接收前端信息
@accept_websocket
def test_socket(request):
if request.is_websocket():
for message in request.websocket:
c=str(message,encoding='utf-8')
print(c)
request.websocket.send(message)
#主动推送消息
@accept_websocket
def test_websocket(request):
if request.is_websocket():
while 1:
time.sleep(1) ## 向前端发送时间
dit = {
'time':time.strftime('%Y.%m.%d %H:%M:%S',time.localtime(time.time()))
}
request.websocket.send(json.dumps(dit))
路由配置urls.py
#websocket
path('socket_test',TemplateView.as_view(template_name='md_admin/socket.html')),
path('websocket_test',TemplateView.as_view(template_name='md_admin/socket_push.html')),
path('test_socket',test_socket),
path('test_websocket',test_websocket),
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
<input id="chat-message-input" type="text" size="100"/><br/>
<input id="chat-message-submit" type="button" value="Send" onclick='sendmessage()'/>
</body>
<script>
//生成socket对象
var socket = new WebSocket("ws:" + window.location.host + "/md_admin/test_socket");
socket.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印服务端返回的数据
};
socket.onclose=function(e){
console.log(e);
socket.close(); //关闭TCP连接
};
if (socket.readyState == WebSocket.OPEN){
socket.onopen();
}
window.s = socket;
function sendmessage(){
window.s.send(document.getElementById("chat-message-input").value);
}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
</body>
<script>
//生成socket对象
var socket = new WebSocket("ws:" + window.location.host + "/md_admin/test_websocket");
socket.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印服务端返回的数据
};
socket.onclose=function(e){
console.log(e);
socket.close(); //关闭TCP连接
};
if (socket.readyState == WebSocket.OPEN){
socket.onopen();
}
</script>
</html>
可以看到,前后端无论是前端发送消息,还是后端主动推送消息,全部基于websocket,实现了真正意义上的实时通信,另外基于dwebsocket的聊天室可以在这里下载源码
https://gitee.com/QiHanXiBei/mei_do_mall/blob/master/dj_websocket.zip