django服务器消息推送,python websocket Django 实时消息推送

本文介绍了WebSocket协议以及如何在Django项目中使用dwebsocket库来实现WebSocket双向通信。通过创建WebSocket链接,监听并处理客户端消息,以及处理连接断开的情况,展示了WebSocket在服务端和客户端的实现细节。同时,文章提到了Nginx和uWSGI的部署配置,以确保WebSocket服务的正常运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebSocket 是什么?

WebSocket 是 HTML5 提供的一种浏览器与服务器间进行全双工通讯的协议。依靠这种协议可以实现客户端和服务器端 ,一次握手,双向实时通信。

1. django-websocket 是旧版本的,现在已经没有人维护了。dwebsocket是新版的,推荐使用dwebsocket;

安装dwebsocket

python setup.py install

整个demo:

1.项目结构:​

20fb93445457151b33b9fb419fb4d9f4.png

2.HelloWorld项目代码:

urls.py代码:

from django.conf.urls import url

from django.contrib import admin

import views

urlpatterns = [

url(r'^admin/', admin.site.urls),

url(r'^index/(?P\w+)', views.gotoIndex),

url(r'websocketLink/(?P\w+)', views.websocketLink)# webSocket 链接

]

views.py

# coding=utf8

from django.shortcuts import render

import threading

from models import Ad

from dwebsocket.decorators import accept_websocket

import json

# from model_admin.models import MessageLog

# 跳转到主页

def gotoIndex(request, username):

return render(request, 'index.html', {'username': username})

# 存储连接websocket的用户

clients = {}

# 记录连接人数 其实没什么卵用 = =

count = 0

# 连接websocket ws://localhost:8000/websocketLink/22

# 因为 websocket 是协议 所以不能用 http或https

@accept_websocket

def websocketLink(request, username):

'连接websocket'

global count

# 获取连接

if request.is_websocket:

lock = threading.RLock()#rlock线程锁

try:

lock.acquire()#抢占资源

s = {}

# 因为同一个账号打开多个页面连接信息是不同的

if clients.get(username) != None:

# 连接信息 键 连接名 值:连接保存

s[str(request.websocket)] = request.websocket

# 已存在的连接信息继续增加

clients[username].update(s)

else:

# 人数加1

count = count + 1

# 连接信息 键 连接名 值:连接保存

s[str(request.websocket)] = request.websocket

# 新增 用户 连接信息

clients[username] = s

print("用户人数" + str(count))

# 监听接收客户端发送的消息 或者 客户端断开连接

sql = ("select id,code,name "

"from "

"prov_ad order by create_date desc limit 1"

)

data_list = Ad.objects.raw(sql)

datas = []

for item in data_list:

datas.append({

'id': item.id,

'name': item.name, # 区域名称

'code': item.code, # 区域编码

'long': item.long, # 经度

'lat': item.lat # 纬度

})

send(username,datas)

except Exception as e:

print e

finally:

# 通过用户名找到 连接信息 再通过 连接信息 k 找到 v (k就是连接信息)

clients.get(username).pop(str(request.websocket))

#释放锁

lock.release()

# 发送消息

def websocketMsg(client, msg):

import json

# 因为一个账号会有多个页面打开 所以连接信息需要遍历

for cli in client:

'client客户端 ,msg消息'

b1 = json.dumps(msg).encode('utf-8')

client[cli].send(b1)

# 服务端发送消息

def send(username, title, data, url):

'username:用户名 title:消息标题 data:消息内容,消息内容:ulr'

try:

if clients[username]:

websocketMsg(clients[username], { 'data': data})

except BaseException:

pass

finally:

pass

index.html代码:

{% load static %}

django-websocket

var websocket;

var userId=$("#userId").val();

var name= '{{username}}';

var lockReconnect = false; //避免ws重复连接

var ws = null; // 判断当前浏览器是否支持WebSocket

var wsUrl = "ws://localhost:9000/websocketLink/"+name;

createWebSocket(wsUrl); //连接ws

function createWebSocket(url) {

try{

if('WebSocket' in window){

ws = new WebSocket(url);

}else if('MozWebSocket' in window){

ws = new MozWebSocket(url);

}else{

alert("您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!");

}

initEventHandle();

}catch(e){

reconnect(url);

console.log(e);

}

}

function initEventHandle() {

ws.onclose = function () {

reconnect(wsUrl);

console.log("llws连接关闭!" + new Date().toUTCString());

};

ws.onerror = function () {

reconnect(wsUrl);

console.log("llws连接错误!");

};

ws.onopen = function () {

console.log("llws连接成功!" + new Date().toUTCString());

heartCheck.reset().start(); //心跳检测重置

};

ws.onmessage = function (event) { //如果获取到消息,心跳检测重置

console.log("llws收到消息啦:" + event.data);

if (event.data != 'pong') {

var obj = eval("(" + event.data + ")");

var data =JSON.parse(event.data)

}

heartCheck.reset().start(); //心跳检测重置

}

}

// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。

window.onbeforeunload = function() {

ws.close();

}

function reconnect(url) {

if(lockReconnect) return;

lockReconnect = true;

setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多

createWebSocket(url);

lockReconnect = false;

}, 544000);

}

//心跳检测

var heartCheck = {

timeout: 5403000, //9分钟发一次心跳

timeoutObj: null,

serverTimeoutObj: null,

reset: function(){

clearTimeout(this.timeoutObj);

clearTimeout(this.serverTimeoutObj);

return this;

},

start: function(){

var self = this;

this.timeoutObj = setTimeout(function(){

//这里发送一个心跳,后端收到后,返回一个心跳消息,

//onmessage拿到返回的心跳就说明连接正常

ws.send("ping");

console.log("ping!")

self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了

ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次

}, self.timeout)

}, this.timeout)

}

}

发送消息

关闭websocket

Nginx部署dwebsocket服务

如果项目部署到nginx服务上,你的项目要用到dwebsocket服务

我使用的是nginx+uwsgi

一.首要需要启一个主服务:

配置nginx.conf、uwsgi.ini,正常启动服务就可以了。

二.还需要启动websocket服务,才能让ws://服务器ip进行通信

1.在项目对应的settings.py里添加下面配置,不然会提示报错:handshake的返回400,也就是客户端不合法

WEBSOCKET_FACTORY_CLASS="dwebsocket.backends.uwsgi.factory.uWsgiWebSocketFactory"

2.在新的uwsgi.ini文件里添加下面配置:

DJANGO_SETTINGS_MODULE=项目路径.settings

启动websocket服务

3.项目里添加的dwebsocket服务就开启了

正如图中所示:

c22c05c11b561fbc088b561573c37743.png

运行效果入下:

ef77cf5dfe254b344ae2e7179cd3c709.png

467e5dc314fceea723c57e7928f1b76f.png

标签:username,function,websocket,python,Django,ws,data,连接

来源: https://blog.51cto.com/u_12768449/2771640

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值