1.1 Websocket原理
1、什么是webSocket?
1.webSocket实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。
2.传统的HTTP协议是无状态的,客户端发送request请求,服务端返回response就结束,而服务端很难主动向客户端发送数据;
远古时期解决方案就是轮训:客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动(浪费流量和资源)
2、webSocket应用场景?
1. 聊天软件:最著名的就是微信,QQ,这一类社交聊天的app
2. 弹幕:各种直播的弹幕窗口
3. 在线教育:可以视频聊天、即时聊天以及其与别人合作一起在网上讨论问题…
3、图解http与webSocket比较
1. 浏览器通过 JavaScript 向服务端发出建立 WebSocket 连接的请求
2. 在 WebSocket 连接建立成功后,客户端和服务端就可以通过 TCP连接传输数据。
3. 因为WebSocket 连接本质上是 TCP 连接,不需要每次传输都带上重复的头部数据
1.2 webSocket使用
1、webSocket使用说明
1. 如果你想为一个单独的视图处理一个websocklet连接可以使用accept_websocket装饰器,它会将标准的HTTP请求路由到视图中。
2. 使用require_websocke装饰器只允许使用WebSocket连接,会拒绝正常的HTTP请求。
3. 在设置中添加设置MIDDLEWARE_CLASSES=dwebsocket.middleware.WebSocketMiddleware这样会拒绝单独的视图实用websocket,必须加上accept_websocket 装饰器。
4. 设置WEBSOCKET_ACCEPT_ALL=True可以允许每一个单独的视图实用websockets
2、Django的Websocket
1)dwebsocket介绍
1. dwebsocket 是一个在 django 用来实现 websocket 服务端的三方模块,使用上手非常简单
2. 安装方式如下:pip install dwebsocket
3. git 地址:https://github.com/duanhongyi/dwebsocket
2)dwebsocket方法
首先是两个基本的装饰器,用来限定过滤 websocket 的连接
dwebsocket.accept_websocket # 允许 http 与 websocket 连接
dwebsocket.require_websocke # 只允许 websocket 连接
1.request.is_websocket() :如果是个websocket请求返回True,如果是个普通的http请求返回False,可以用这个方法区分它们。
2.request.websocket() :websocket请求建立之后,有一个websocket属性,如果request.is_websocket()是False,这个属性将是None。
3.WebSocket.wait() :返回一个客户端发送的信息,在客户端关闭连接之前他不会返回任何值,这种情况下,方法将返回None
4.WebSocket.read() :如果没有从客户端接收到新的消息,read方法会返回一个新的消息,如果没有,就不返回。这是一个替代wait的非阻塞方法
5.WebSocket.count_messages() :返回消息队列数量
6.WebSocket.has_messages() : 如果有新消息返回True,否则返回False
7.WebSocket.send(message) :向客户端发送消息
8.WebSocket.__iter__() :websocket迭代器
3、HTML的Websocket
1)响应事件
# 1. 创建一个WebSocket连接 var ws = new WebSocket("ws://127.0.0.1:8001/echo") # 2. ws.onopen方法(当 ws 连接建立时触发) ws.onopen = function () { console.log('WebSocket open'); //成功连接上Websocket }; # 3. 当 ws 连接接收到数据时触发 ws.onmessage = function (e) { console.log('message: ' + e.data); //打印出服务端返回过来的数据 }; # 4. 当 ws 连接发生通信错误时触发 ws.onerror = function () { console.log('连接出错'); }; # 5. 当连接关闭时触发 ws.onclose = function(){ console.log('连接关闭') }
2)方法
ws.send(str) // 通过ws连接发送数据
ws.close() // 关闭ws连接
4、django+webSocket简单事例
from django.conf.urls import url from django.contrib import admin from app01 import views as v urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', v.index), url(r'^echo$', v.echo), ]
from django.shortcuts import render from dwebsocket.decorators import accept_websocket,require_websocket from django.http import HttpResponse def index(request): return render(request, 'index.html') @accept_websocket def echo(request): if not request.is_websocket(): #判断是不是websocket连接 try: #如果是普通的http方法 message = request.GET['message'] return HttpResponse(message) except: return render(request,'index.html') else: for message in request.websocket: request.websocket.send(message)#发送消息到客户端
DOCTYPE html>
<html>
<head>
<title>django-websockettitle>
head>
<body>
<input type="text" id="message" value="Hello, World!" />
<button type="button" id="connect_websocket">连接 websocketbutton>
<button type="button" id="send_message">发送 messagebutton>
<button type="button" id="close_websocket">关闭 websocketbutton>
<h1>Received Messagesh1>
<div id="messagecontainer">div>
<script src="http://code.jquery.com/jquery-1.11.1.min.js">script>
<script type="text/javascript">
$(function () {
$('#connect_websocket').click(function () {
if (window.s) {
window.s.close()
}
/*创建socket连接*/
var ws = new WebSocket("ws://" + window.location.host + "/echo");
console.log(ws, 88888888888888888)
ws.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
};
ws.onmessage = function (e) {
console.log('message: ' + e.data);//打印出服务端返回过来的数据
$('#messagecontainer').prepend('' + e.data + '');
};
// Call onopen directly if socket is already open
if (ws.readyState == WebSocket.OPEN) ws.onopen();
window.s = ws;
});
$('#send_message').click(function () {
//如果未连接到websocket
if (!window.s) {
alert("websocket未连接.");
} else {
window.s.send($('#message').val());//通过websocket发送数据
}
});
$('#close_websocket').click(function () {
if (window.s) {
window.s.close();//关闭websocket
console.log('websocket已关闭');
}
});
});
script>
body>
html>
1.3 websocket心跳包机制
1、心跳包的意义
1. 在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件。
2. 这样会有:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失。
3. 所以就需要一种机制来检测客户端和服务端是否处于正常的链接状态。
4. 因此就有了websocket的心跳了,还有心跳,说明还活着,没有心跳说明已经挂掉了。
2、实现心跳检测的思路
1. 每隔一段固定的时间,向服务器端发送一个ping数据,如果在正常的情况下,服务器会返回一个pong给客户端
2. 如果客户端通过onmessage事件能监听到的话,说明请求正常
3. 如果是网络断开的情况下,在指定的时间内服务器端并没有返回心跳响应消息,因此服务器端断开了。
4. 服务断开我们使用ws.close关闭连接,在一段时间后,可以通过 onclose事件监听到。
5. 因此在onclose事件内,我们可以调用 reconnect事件进行重连操作。
11111111111111111