通过Django Channels设计聊天机器人WEB框架
这两个月都在忙着设计针对银联客服业务的智能聊天机器人,上一周已经交完设计报告,这一周还和部门同事一起分享了系统设计及运行效果。因为时间的关系,系统原型我使用了Flask+jQuery的组合,感觉用以原型可以,上线使用存在性能拓展瓶颈。最近技术调研发现Django框架中自带了实时通信的工具包Channels,网上评价不错,因此测试使用并记录。
在本文中,我们将通过Django Channels打造一个聊天机器人的WEB框架,主要实现前后端的信息交互。
参考文档
Django Channels介绍
首先要理解Django现有的请求响应策略是这样的:浏览器发出请求,Django服务器接受请求后通过路由匹配该请求到某个视图,视图将会返回一个响应并由服务器发送回浏览器。类似的请求响应在Flask实现也是如此。对于一般性的网页浏览(比如新闻阅读),这样的响应机制是没有问题的,但对于需要一个保持不断会话的请求来说,这是行不通的,因为Django的声明周期只能存在一个请求中,它不能让服务器在没有请求的情况下不断地发送数据岛浏览器客服端。这样的场景目前正在不断地涌现,例如在线聊天室,会话机器人,以及最近很流行的微服务应用。
Channels改变了Django的工作方式,让它实现了一种包括通道、消费者和worker的worker监听的模式,所有消费者都会分配有单独的通道,worker监听通道的消息,确保消息到来时能进行处理。为了确保上述机制运行,Channels需要有三个工作层:
- 接口服务器,Django和用户(浏览器)之间通信的桥梁,包括一个实现WSGI协议的适配器和一个独立的websocket服务器。
- 通道后端, 在接口服务器和worker之间传递消息,由插拔式的python代码和存储组成,存储可以是内存、数据库或者redis,推荐使用redis,兼具其余两者的优点。
- worker,监听所有channel,当有新消息到来时候唤醒功能函数。
Channels可以让Django的框架变得更为可靠和可拓展,整个通信的服务器数可以按需拓展,至少保证一台协议服务器和一台工作服务器即可。使用Channels后,你不再需要组织code去为异步调用,Channls已经将一切都已经帮你准备好。
关于Channels的介绍,我推荐大家看一下第二篇参考文档,虽然全英文的,但是看起来不是很吃力,作者很是体谅我等词汇量不够的读者啊。
实验教程
本篇教程的开发环境如下,默认大家已经准备好。关于Windows redis的安装可以参见我之前的博文。
- Windows7
- Python2.7.13
- pyCharm2016.2
- redis 3.0.53 Windows x64
本实验的目的是搭建一个用于聊天机器人的WEB交互框架,可以直接拉到最下方看实现效果。
note: 下面的代码运行需要redis服务开启了6379端口正常运行。
Step1:安装第三方工具包,建议通过pip install -r的方式安装。
asgi-redis==1.0.0
asgiref==1.0.0
attrs==16.3.0
autobahn==0.17.1
Automat==0.5.0
channels==1.0.3
constantly==15.1.0
daphne==1.0.3
Django==1.10.5
incremental==16.10.1
msgpack-python==0.4.8
redis==2.10.5
six==1.10.0
Twisted==17.1.0
txaio==2.6.1
zope.interface==4.3.3
txredisapi==1.4.4
Step2:新建django项目“example_channels”,建议用pycharm新建很方便
Step3: 分别在以下目录新建文件:
example_channels/example 新增consumers.py,urls.py,新增templates/example子目录,并在该子目录下新增chat.html。
example_channels/example_channels中新增routing.py。完整的目录结构如下:
接下来的内容是如何修改上述文件使得所设计的框架能正常运行。
Step4:修改配置文件,增加channels的配置,你可以认为这是配置Channels的管道
首先修改example_channels/example_channels/setting.py的INSTALLED_APPS 参数
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'example',
]
并增加配置CHANNEL_LAYERS :
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'asgi_redis.RedisChannelLayer',
'CONFIG': {
'hosts': [('localhost', 6379)],
},
'ROUTING': 'example_channels.routing.channel_routing',
}
}
Step5:增加worker来对管道中的消息进行监控
修改example_channels/example/consumers.py文件,增加下面的代码:
from channels import Group
import json
def ws_connect(message):
Group('users').add(message.reply_channel)
message.reply_channel.send({
'text': json.dumps({
'msg': u"你好,很高兴为你服务。",
'talk': False
})
})
def ws_disconnect(message):
Group('users').discard(message.reply_channel)
def ws_receive(message):
data = json.loads(message['text'])
message.reply_channel.send({
'text': json.dumps({
'msg': u"我正在思考你的问题{%s}" % data["text"],
'talk': True
})
})
三个函数可以认为是对三个管道的工作函数,这三个管道在Step6中进行了定义,分别是connect、disconnect、receive,这三个管道代替view起作用。
Step6:在example_channels/example_channels/routing.py中增加管道的定义
from channels.routing import route
from example.consumers import ws_connect, ws_disconnect,ws_receive
channel_routing = [
route('websocket.connect', ws_connect),
route('websocket.receive', ws_receive),
route('websocket.disconnect', ws_disconnect),
]
到Step6为止,我们完成了Channels的配置。我们将在Step7中增加一个页面来测试上述的配置。
Step8:聊天机器人前端框架设计
首先,我们在example_channels/example/templates/example/chat.html添加相应的网页前端代码,确保用户能发送请求到服务器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test Django Channels</title>
</head>
<body>
<div style="text-align: center;margin-top: 50px">
<input id="message" type="text" style="width: 300px" placeholder="输入消息">
<button id="send-message" style="width:80px;margin-left:20px;">发送</button>
</div>
<table id="show-message" style="width: 410px;margin: 0 auto;margin-top: 10px">
<tr>
<td style="text-align: center; border-bottom:1px dashed #000;"><strong>聊天记录</strong></td>
</tr>
</table>
</body>
<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var socket = new WebSocket('ws://' + window.location.host + '/users/');
if (socket.readyState == WebSocket.OPEN) {
socket.onopen();
}
socket.onmessage = function (message) {
var data = JSON.parse(message.data);
updateLog("机器人", data["msg"]);
$("#message").val("");
$("#message").focus();
};
$("#send-message").click(function () {
var inputText = $("#message").val();
if (typeof(inputText) == "undefined" || inputText.length < 1) {
alert("没有输入信息");
}
else {
var msg = {"text": inputText};
socket.send(JSON.stringify(msg));
updateLog("你", inputText);
}
});
function updateLog(name, message) {
var chat = $("#show-message");
var ele = "<tr><td>" + name + ": " + message + "</td></tr>"
chat.append(ele);
}
</script>
</html>
然后需要在服务器上配置该网页的路由,在example_channels/example_channels/urls.py中增加下面的代码:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('example.urls', namespace='example')),
]
并在example_channels/example/urls.py中增加代码:
from django.conf.urls import url
from example.views import chat
urlpatterns = [
url(r'^$', chat, name='chat'),
]
至此,基于Django Channels的聊天机器人设计完成。搞懂上述的配置尤其是Step8需要具备基本的Django知识,这里就不再描述。
测试代码运行效果,在Terminal中输入
D:\PWorkspace\example_channels>python manage.py runserver
运行效果如下:
本文原创,转载前请注明出处
相关的代码上传到github 。
通过Django Channels设计聊天机器人WEB框架的更多相关文章
- Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用
Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...
- 详说Flask、Django、Pyramid三大主流 Web 框架
前言 目前随着 Python 在大数据.云计算.人工智能方面的热度,Python Web 应该也会被更多企业了解使用. Python Web 框架千万种,没必要都去了解和学习,身边总有人说高手都用 F ...
- Django:之不得不说的web框架们
python的web框架 Bottle Bpttle是一个快速.简洁.轻量级的基于WSIG的微型web框架,此框架只有一个.py文件,除了python的标准库外,其不依赖任何其它模块. pip ins ...
- Django(一)自定义web框架
https://www.cnblogs.com/yuanchenqi/articles/6083427.htm 一 什么是web框架 框架,即framework, 特指为解决一个开放性问题而设计的具有 ...
- Django视频教程 - 基于Python的Web框架(全13集)
Django是由Python驱动的开源模型-视图-控制器(MVC)风格的Web应用程序框架,使用Django可以在即可分钟内快速开发一个高品质易维护数据库驱动的应用程序.下面是一大坨关于Django应 ...
- RESTful 设计工具和Web框架
搭建开发环境几乎都搭建失败,因为需要FQ Spring Boot 和 Spring MVC 单独 Jersey官网可以直接访问 https://jersey.java.net/documentatio ...
- Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架
Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ...
- WEB框架本质和第一个Django实例
Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 总的来说:Web框架的本质就是浏览 ...
- Python开发【第二十一篇】:Web框架之Django【基础】
Python开发[第二十一篇]:Web框架之Django[基础] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...
随机推荐
- Cocos2D:塔防游戏制作之旅(二)
一个象牙塔的视图 如果你并不熟悉此类型的游戏,塔防游戏是一个战略游戏,你需要购买和将武装塔放置在战略位置,去阻止一波又一波的敌人到达并摧毁你的基地 每一波敌人都更强,这些更强的对手有着更快的速度和对于 ...
- 固定宽高的DIV绝对居中示例
看了一些代码,然后自己试验了一番,分享如下示例: 实现点: 如果元素的宽高固定,那么,css指定样式为top:50%;left:50%; 而margin-top和 margin-left 指定为负数, ...
- UNIX环境高级编程——UNIX基础知识
1.用户在登陆linux系统时,先键入登录名,然后键入口令.系统在其口令文件(通常是/etc/passwd文件)中查看登录名.口令文件中的登陆项由7个以冒号分隔的字段组成,它们是:登录名.加密口令.数 ...
- android binder理解
Android中的Parcel是什么 Parcel,翻译过来是"打包"的意思.打包干什么呢?是为了序列化. 如果要在进程之间传递一个整数,很简单,直接传就是行了:如果要传 ...
- Visual Studio 2010多线程编程
随着处理数据量的逐渐增大,串行单核的程序,犹如残灯缺月,无法满足运用需求.大规模集群的出现,解决了这一技术难题.本文旨在探讨如何使用多CPU并行编程,关于CUDA的并行前面文章已有讲述.本文结构分为三 ...
- 下载Ext JS 5.1 gpl版本的方法
先进入官网:http://www.sencha.com 然后在导航的Products中选择Sencha Ext JS,会看到以下页面: 这时候不要单击Download按钮,而是要单击导航中的DETAI ...
- Python的time(时间戳与时间字符串互相转化)
strptime("string format")字符串如"20130512000000"格式的 输入处理函数 localtime(float a)时间戳的输入 ...
- Caffe + Ubuntu 15.04 + CUDA 7.0 安装以及配置
作为小码农的我,昨天就在装这个东东了,主要参考第一篇博文,但是过程发现很多问题,经过反反复复,千锤百炼,终于柳暗花明,我把这个caffe给搞定了,是故,我发布出来,后之来者,欲将有感于斯文~ 本分分为 ...
- Android Studio中创建Kotlin For Android项目
Kotlin俗称Android中的Swift,它是Jetbrains公司开发的基于JVM的一门语言,JetBrains公司可能大家并不熟悉,不过相信IntelliJ IDE大家一定知道,Android ...
- Maven部署项目到Tomcat
首先需要用MyEclipse建立一个Maven项目 为了不报403错误,tomcat目录下的tomcat-user.xml文件的配置如下: setting.xml配置如下,大家关注下Server的配置 ...