注明

本笔记主要参考《Django应用开发实战》《Django企业开发实战》,这两本书前者详细,后者精炼。学习之后真的是感觉自己进步了很多。值得一读,如果您遇到了值得一读的书籍,欢迎推荐给我,大家共同进步。


@[TOC](文章目录)


前言

Web聊天室的实现方法有多种,下面将简要介绍一下实现方法

  • AJAX技术利用AJAX实现网页与服务器的无刷新交互。缺点是实时性不高。
  • Coment技术Coment是一种Web应用框架,服务器以异步方式向浏览器推送数据,无需浏览器发送请求,非常适合事件驱动的Web应用,以及对交互性和实时性要求较高的应用。
  • XMPP协议:可扩展消息处理协议,专为及时通信系统设计的通信协议,用于即时消息以及在线探测
  • Flash的XmlSocket:Flash Media Server 是一个强大的流媒体服务器,它基于RTMP协议,提供了稳定的流媒体交互功能,内置远程共享对象的机制,是浏览器创建并连接服务器的远程共享
  • websocket协议:WebSocket是一种在单个TCP连接上进行全双工通信的协议WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket
    API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

django实现websocket大致上有两种方式,一种channels,一种是dwebsocket。channels依赖于redis,twisted等


提示:以下是本篇文章正文内容,下面案例可供参考

一、Channels?

Channels安装与配置

pip install channels
pip channels_redis
pip install pypiwin32

settings配置

INSTALLED_APPS = [
'django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','channels', # 添加channels功能'chat',
]
ASGI_APPLICATION = '项目名.routing.application'
CHANNEL_LAYERS = {'default': {'BACKEND': 'channels_redis.core.RedisChannelLayer','CONFIG': {"hosts": [('127.0.0.1', 6379)],},},
}

说明:

  • CHANNEL_LAYERS用于设置Redis数据库的连接方式.
  • ASGI_APPLICATION:代表routing.py定义的application对象。

项目名文件夹下定义routing.py

from channels.routing import ProtocolTypeRouter
from channels.routing import URLRouter
from .urls import websocket_urlpatternsapplication = ProtocolTypeRouter({# (http->django views is added by default)'websocket': AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
})

说明:

定义这个文件是为了响应ASGI_APPLICATION定义application对象,将Django与该插件建立连接。

在项目名文件夹下urls.py,定义websocket_urlpatterns

from django.urls import path, include
from .consumers import ChatConsumer
urlpatterns = [path('', include(('chat.urls', 'chat'), namespace='chat'))
]websocket_urlpatterns = [path('ws/chat/<room_name>/', ChatConsumer),
]

说明:

  • websocket_urlpatterns用于定义Channels的路由信息,上数定义的路由ws/chat/<room_name>/,它是由consumers.py的ChatConsumer处理和响应HTTP请求的,该路由作为Channels的API接口由网页的Javascript与该路由构建通信连接,使浏览器和服务器之间相互传递数据。

最后定义consumers.py

# from asgiref.sync import async_to_sync
# from channels.generic.websocket import WebsocketConsumer
# import json
#
# # 将消费者代码为同步。
# class ChatConsumer(WebsocketConsumer):
#     def connect(self):
#         self.room_name = self.scope['url_route']['kwargs']['room_name']
#         self.room_group_name = 'chat_%s' % self.room_name
#
#         # Join room group
#         async_to_sync(self.channel_layer.group_add)(
#             self.room_group_name,
#             self.channel_name
#         )
#
#         self.accept()
#
#     def disconnect(self, close_code):
#         # Leave room group
#         async_to_sync(self.channel_layer.group_discard)(
#             self.room_group_name,
#             self.channel_name
#         )
#
#     # Receive message from WebSocket
#     def receive(self, text_data):
#         text_data_json = json.loads(text_data)
#         message = text_data_json['message']
#
#         # Send message to room group
#         async_to_sync(self.channel_layer.group_send)(
#             self.room_group_name,
#             {#                 'type': 'chat_message',
#                 'message': message
#             }
#         )
#
#     # Receive message from room group
#     def chat_message(self, event):
#         message = event['message']
#
#         # Send message to WebSocket
#         self.send(text_data=json.dumps({#             'message': message
#         }))#-------------low------------
# 将消费者代码重写为异步,以提高其性能。
from channels.generic.websocket import AsyncWebsocketConsumer
import jsonclass ChatConsumer(AsyncWebsocketConsumer):async def connect(self):self.room_name = self.scope['url_route']['kwargs']['room_name']self.room_group_name = 'chat_%s' % self.room_name# Join room groupawait self.channel_layer.group_add(self.room_group_name,self.channel_name)await self.accept()async def disconnect(self, close_code):# Leave room groupawait self.channel_layer.group_discard(self.room_group_name,self.channel_name)# Receive message from WebSocketasync def receive(self, text_data):text_data_json = json.loads(text_data)message = text_data_json['message']# Send message to room groupawait self.channel_layer.group_send(self.room_group_name,{'type': 'chat_message','message': message})# Receive message from room groupasync def chat_message(self, event):message = event['message']# Send message to WebSocketawait self.send(text_data=json.dumps({'message': message}))

下面可以很简单的实现在线聊天功能

大致思路:在应用urls中设置两个路由:创建聊天和进入聊天室。在创建聊天室后即跳转到进入聊天室路由。进入聊天室路由网页设置:使网页与项目插件连接,设置接收和发送信息(也可以设置异常事件触发器)。下面步骤

chat urls

from django.urls import path
from .views import *urlpatterns = [# 用于开启新的聊天室path('', newChat, name='newChat'),# 创建聊天室path('<room_name>/', room, name='room'),
]
chat views
from django.shortcuts import render
# 用于创建或进入聊天室
def newChat(request):return render(request, 'chat.html', locals())# 创建聊天室
def room(request, room_name):return render(request, 'room.html', locals())
chat.html(截取部分重要)
<body><div>请输入聊天室名称</div><br/><input id="input" type="text" size="30"/><br/><input id="submit" type="button" value="进 入"/><script>document.querySelector('#input').focus();document.querySelector('#input').onkeyup = function(e) {if (e.keyCode === 13) {  // enter, returndocument.querySelector('#submit').click();}};document.querySelector('#submit').onclick = function(e) {var roomName = document.querySelector('#input').value;window.location.pathname = '/' + roomName + '/';};</script>
</body>
说明:
确定聊天室名称后,单击进入或者回车将触发javaScript脚本。

room.html

<body><textarea id="chat-log" cols="50" rows="6"></textarea><br/><input id="input" type="text" size="50"/><br/><input id="submit" type="button" value="发 送"/>
</body>
<script>var roomName = '{{ room_name }}';var chatSocket = new WebSocket('ws://' + window.location.host +'/ws/chat/' + roomName + '/');chatSocket.onmessage = function(e) {var data = JSON.parse(e.data);var message = data['message'];document.querySelector('#chat-log').value += (message + '\n');};chatSocket.onclose = function(e) {console.error('Chat socket closed unexpectedly');};document.querySelector('#input').focus();document.querySelector('#input').onkeyup = function(e) {if (e.keyCode === 13) {  // enter, returndocument.querySelector('#submit').click();}};document.querySelector('#submit').onclick = function(e) {var messageInputDom = document.querySelector('#input');var message = messageInputDom.value;chatSocket.send(JSON.stringify({'message': message}));messageInputDom.value = '';};
</script>
说明:var chatSocket部分为了网页与项目插件连接chatSocket.onmessage接收数据,并展示到文本框chatSocket.onclose关闭连接,当出现异常时触发document.querySelector发送数据querySelector将文本展示到网页textarea组件中。

Django插件Channels ——实现即时通信相关推荐

  1. Django与Channels实现WebSocket

    文章目录 WebSocket ajax轮询 long poll Websocket Channels WSGI ASGI Django中使用 信息交互的周期 前端实现WebSocket 前后端分离项目 ...

  2. android即时通讯ui框架,android IM即时通信之聊天界面UI框架

    写在最前面 现在很多软件都要求加入即时通信的功能,当然很多都用了三方(环信.融信...).最近,项目也有此需求,我们选择的是环信.环信也提供了UI框架,但是说实在的一般的应用用不了那么多功能,可能就简 ...

  3. 腾讯TIM实现即时通信 v3+ts实践

    目录 初始化sdk 功能描述 初始化 准备 SDKAppID 调用初始化接口 监听事件 发送消息 创建消息 创建文本消息 登录登出 功能描述 登录 登出 销毁 登录设置 获取会话列表 功能描述 获取会 ...

  4. [Web端接入经验分享] 腾讯云即时通信TIM、实时音视频TRTC

    [Web端接入经验分享] 腾讯云即时通信TIM.实时音视频TRTC 即时通信TIM官网地址 即时通信TIM SDK API文档地址 实时音视频TRTC官网地址 实时音视频TRTC SDK API文档地 ...

  5. uni-app 快速集成 IM 即时通信的方法——TUIKit 来啦

    uni-app 是目前比较火的跨平台框架,腾讯云即时通信 IM 正式推出支持三大平台的 uni-app TUIKit. TUIKit 是基于 IM SDK 实现的一套 UI 组件,其包含会话.聊天.群 ...

  6. TIM腾讯聊天(即时通信 IM)(咨询客服业务)

    即时通信 IM 介绍 即时通信IM产品简介 应用场景 1. 社交沟通 即时通信 IM 为应用于社交沟通提供能力支持,可实现单聊.群聊.弹幕等多种聊天模式,支持文字.图片.语音.短视频等多种消息类型,实 ...

  7. vue 使用腾讯IM即时通信

    最近在做商城类的项目,需要使用到客服系统, 用户选择的腾讯IM即时通信,文档很.... 对Web很不友好, 弄了半天,总算出来. 1. 先安装依赖 cnpm i cos-js-sdk-v5 cnpm ...

  8. uniapp集成腾讯即时通信IM,实现一对一聊天,支持文字、表情、语音、图片、视频

    uniapp集成腾讯即时通信IM,实现一对一聊天,支持文字.表情.语音.图片.视频 原则 拿来即用,节省开发时间 介绍 腾讯的给的例子内容比较乱,我花了好长时间才集成出来,然后对聊天页面做了UI美化. ...

  9. web直播+聊天室功能(阿里云播放器和即时通信IM聊天、消息自动滚动)

    左边为视频直播,右边为聊天 解决问题: 1.直播的时候,播放器可以点击,并且可以暂停,解决办法是在播放器上加一次遮罩 2.tim聊天功能要注册阿里云的账号,下载自己的sdk和js插件 3.直播功能下载 ...

最新文章

  1. linux获取命令的返回值,怎样获取shell函数的返回值及shell命令的返回值?
  2. 如何用代码的方式取出SAP C4C销售订单创建后所有业务伙伴的数据
  3. 用eclipse创建WebService项目
  4. php加密 java rsa_PHP的DES加密和RSA签名(兼容java)
  5. 自动档汽车正确的操作方法和习惯---请教贴
  6. python读取xls文件_从python中的xls读取unicode
  7. 第一次迭代 一次会议
  8. 获取整数的最大值最小值
  9. 2022年起重机械指挥判断题及答案
  10. word里双横线怎么打_在word中怎么画直线、双直线、虚线
  11. 解决IE7无法设置空白页的办法
  12. 汇佳学校新推“未来艺术大师”项目 实现学术艺术双赢
  13. C51 (矩阵键盘密码锁)
  14. 分布式之gossip共识算法分析
  15. php对接海康api样例
  16. [Step By Step]SAP HANA中创建分析视图(Analytic View)
  17. 华为桌面云 服务器可以虚拟多少,桌面云一台服务器虚拟多少
  18. 安科瑞油烟浓度在线监控仪在江苏省某县餐饮油烟监测治理项目中的应用
  19. bcb获取计算机名称,win7老电脑共享打印机无法连接0x00000bcb错误的修复方法
  20. 智能工业机器人在各行业领域中的应用有哪些呢?

热门文章

  1. RFID停车场收费系统
  2. 什么是DI(依赖注入)
  3. unc 目录不受支持_DOS批处理不支持将UNC 路径作为当前目录的巧妙解决方案
  4. 前端 - 博客系统(页面设计) - JavaEE初阶 - 细节狂魔
  5. 【原创】简单尝试脱“爱加密”官网加固的DEX壳--二代抽取壳(dexhunter工具应用)
  6. java雪花纷飞_分析自定义view的实现过程-实现雪花飞舞效果(转载有改动)
  7. 那些你不知道的MapStruct用法——Mapstruct自定义映射
  8. 北大青鸟APTECH(青岛银河)培训中心
  9. mysql to geode_万事达卡使用Apache Geode防范欺诈
  10. 化工厂定位需要考虑哪些因素呢?你又知道化工厂定位需要哪些因素?--新导智能