所谓Web即时通信,有点类似很久之前接触到的 3GQQ聊天,微信网页版。
前几天,有个学弟请教Django实现网页在线聊天的功能,结合杨抒老师也曾提过马产业科技创新平台拍卖系统 WebSocket、心跳检测 相关的东西,觉得很有意思,因此利用业余休息时间,进行整理测试,最终实现了Web在线聊天的功能,将所得做些整理。
现有CSDN博客的博主,多数都是通过自动回复、或者图灵聊天机器人进行回复,未涉及到两个真人即时聊天的功能,因此,在本文中将实现两个真人进行通信的功能。
通过学弟的功能介绍,进行了分析,很容易得出认为即时通信,即两个用户之间建立WebSocket的误区。经过功能实践,得出结论,实际上是:用户分别与服务器建立WebSocket通信,然后服务器通过判断来源用户和接受用户,以对来源用户的信息进行转发,发送给接受用户,以此实现即时通信的功能。
Django: Python语言开发的一款Web开发框架。
dwebsocket:Django WebSocket通信第三方库,只支持django 2版本。
LayIM:LayUI开发的网页即时聊天UI框架,该框架需要购买授权。
在承接某项目是购买全套LayUIAdmin后台框架授权时赠送。
1、引入相应静态文件
2、核心通信函数【以A用户为例】
// 建立通信 A用户 和 B用户 建立通信前 走不同路由
var socket = new WebSocket("ws://" + "127.0.0.1:8000" + "/send/");
// 监听发送消息
layim.on('sendMessage', function (data) {
var To = data.to;
socket.send(JSON.stringify({
type: 'chatMessage' //随便定义,用于在服务端区分消息类型
, data: data['mine']['content']
}));
if (To.type === 'friend') {
layim.setChatStatus('<span style="color:#FF5722;">对方正在输入...</span>');
}
});
// 监听接收消息
socket.onmessage = function (res) {
var res = JSON.parse(res['data']);
setTimeout(function () {
//接受消息(如果检测到该socket)
layim.getMessage({
username: "用户B"
, avatar: layui.cache.layimAssetsPath + "images/default.png"
, id: "100001"
, type: "friend"
, content: res.data
});
}, 2000);
};
Tips: Django 3+ 不再支持 dwebsocket,官方推荐采用 channels
后续本博客更新将采用channels
1、安装dwebsocket
pip3 install dwebsocket
2、在 INSTALLED_APPS 加入 dwebsocket
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'......',
'dwebsocket',
'......',
]
3、在 settings.py 中进行相关设定
# dwebsocket 配置
import dwebsocket # 部分博主说将该语句放在该文件开头,个人测试不行
MIDDLEWARE_CLASSES=['dwebsocket.middleware.WebSocketMiddleware']
# 可以允许每一个单独的视图使用websockets
WEBSOCKET_ACCEPT_ALL=True
def user_a(request):
"""
A用户 即时通信页面
:param request:
:return:
"""
return render(request, 'user-a.html')
def user_b(request):
"""
B用户 即时通信页面
:param request:
:return:
"""
return render(request, 'user-b.html')
# 此处若只有两人通信,可以做以下操作
# 若用户有很多人,建议对建立通信的两人进行分组管理
userA = {}
userB = {}
@accept_websocket
def socket_a(request):
"""
用户A 建立 Socket 通信
:param request:
:return:
"""
if request.is_websocket():
userid = str(uuid.uuid1())
# 判断是否有客户端发来消息,若有则进行处理,若发来“test”表示客户端与服务器建立链接成功
while True:
message = request.websocket.wait()
if not message:
break
else:
print("客户端链接成功:" + str(message, encoding="utf-8"))
# 保存客户端的ws对象,以便给客户端发送消息,每个客户端分配一个唯一标识
userA[userid] = request.websocket
# 发送消息
send_msg(message, userB)
@accept_websocket
def socket_b(request):
"""
用户B 建立 Socket 通信
:param request:
:return:
"""
if request.is_websocket():
userid = str(uuid.uuid1())
# 判断是否有客户端发来消息,若有则进行处理,若发来“test”表示客户端与服务器建立链接成功
while True:
message = request.websocket.wait()
if not message:
break
else:
print("客户端链接成功:" + str(message, encoding="utf-8"))
# 保存客户端的ws对象,以便给客户端发送消息,每个客户端分配一个唯一标识
userB[userid] = request.websocket
send_msg(message, userA)
def send_msg(msg, clients):
"""
转发消息
:param msg: 消息内容
:param client: 接收用户唯一标识
:return:
"""
# 若多人中两人进行通信,无需遍历,指定分组管理的用户客户端即可
for client in clients:
clients[client].send(msg)
return JsonResponse({"msg": "success"})
因LayIM需要额外购买授权,因此在项目中删除了LayIM相关文件,只供显示后端程序代码,如需授权,请点击购买授权:LayIM官网
因 Django 3+ 推荐使用channels, 且dwebsocket更新时间久远,因此在Django 2较新版本中不稳定,不建议在生产环境中使用。
将使用 channels 库在Django完成以上效果。
本文由 代码君 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
原文链接:https://www.loseboy.cn/archives/djangolayim实现websocket通信
最后更新:2021-04-26 02:19:27
Update your browser to view this website correctly. Update my browser now