ReconnectingWebSocket 是一个小型的 JavaScript 库,封装了 WebSocket API ,用它可以实现服务器向客户端推送数据。避免了客户端频繁发起请求。
Django是建立在请求和响应的简单概念之上的:浏览器发出请求,Django调用一个视图,它返回一个响应并发送回浏览器,这就完成了一次请求。
Django Channels:取代了Django中的“guts” ——请求/响应周期发送跨通道的消息。Channels允许Django以非常类似于传统HTTP的方式支持WebSockets。Channels也允许在运行Django的服务器上运行后台任务。HTTP请求表现以前一样,但也通过Channels进行路由。
JS代码
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
var ws_path = ws_scheme + '://' + window.location.host + "/message/" + "{{ user.UserID }}/" + "stream/";
console.log("Connecting to " + ws_path);
var socket = new ReconnectingWebSocket(ws_path);
// Handle incoming messages
socket.onmessage = function (message) {
// 处理服务器推送过来的数据
};
// Helpful debugging
socket.onopen = function () {
//链接打开
console.log("Connected to notification socket");
}
socket.onclose = function () {
//链接关闭
console.log("Disconnected to notification socket");
}
Django 服务端代码
#setting配置
CHANNEL_LAYERS = {
"default": {
# This example app uses the Redis channel layer implementation asgi_redis
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [(redis_host, 6379)],
},
"ROUTING": "channel_routing",#路由名字
},
}
#路由
channel_routing = [
# Called when incoming WebSockets connect 连接上
route("websocket.connect", connect_blog, path=r'^/message/(?P<slug>[^/]+)/stream/$'),
# Called when the client closes the socket 断开
route("websocket.disconnect", disconnect_blog, path=r'^/message/(?P<slug>[^/]+)/stream/$'),
]
def connect_blog(message, slug):#链接上来的方法
Group(liveblog.group_name).add(message.reply_channel)
def disconnect_blog(message, slug):#断开的方法
Group(liveblog.group_name).discard(message.reply_channel)
#发送的时候直接再Group组里面找到对应的message.reply_channel,然后send出去
Group(blog.group_name).send({
# WebSocket text frame, with JSON content
"text": json.dumps(notification),
})