美文网首页
mac使用Django搭建后台服务器并添加实时通讯功能

mac使用Django搭建后台服务器并添加实时通讯功能

作者: Double_Chen | 来源:发表于2018-01-10 17:50 被阅读866次

这篇文章介绍如何通过Django框架搭建一个后台,实现接口编写、实时通讯以及推送功能。

我使用的工具:
PyCharm 用于编写代码,破解方法在这里,如果不行请自行找其他方式破解
Postman 用于测试接口
mysql 服务器数据库操作我选用的是mysql,不过本文不打算讲数据库的东西,可以不装

学习过程中参考链接:
廖雪峰Python教程,学习Python的基本使用
菜鸟教程,学习环境的搭建和使用,本文主要内容

建议安装好我上面提到的工具,还有上面菜鸟教程的内容和本文编写接口功能基本类似,可以直接参考该链接。还有Django是需要先安装的,我是通过pip3 install django进行安装的,安装详细教程也可以参考菜鸟教程上。

开始

首先新建一个项目,打开终端cd到一个目录下,执行语句既可创建一个Django项目,helloworld表示项目文件名,可自定义

$ cd desktop
$ django-admin.py startproject helloworld
文件内容

目录说明:

  • hellowrold:项目容器
  • manage.py:命令行工具,可以让你通过命令行与该Django交互。比如数据库操作
  • hellowrold/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。不常使用但是是必须的
  • hellowrold/settings.py: 该 Django 项目的设置/配置。经常使用
  • hellowrold/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。可以看做是后台api接口
  • hellowrold/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。没用过

新建一个app

cd这个项目,创建一个app,app名为example,表示该项目的一个分支

python manage.py startapp example

然后在setting文件的INSTALLED_APPS里添加 'example'


屏幕快照 2018-01-10 15.48.28.png

启动服务器

1.用pycharm打开该项目,右上角-file-open,此时在pycharm上运行(run)成功。

2.或者在终端(teminal) cd 到该helloworld文件路径,通过输入命令来启动服务器,这个路径要注意不要弄错,要确定是manage.py文件的目录

$ cd 路径/hellowrold
$ python manage.py runserver 0.0.0.0:8000  //8000指的是端口号,不说明的情况下为8000,也可以自行修改

这样就启动了服务器,打开浏览器输入127.0.0.1:8000即可看到It worked!,说明服务器启动成功。

让周围设备也能进入到本机的服务器

通过pycharm运行启动的服务器,只能在本机上查看到,即在浏览器上输入127.0.0.1:8000,而同一网络下的手机或电脑都无法查看,要让周围设备也能进入,必须使用终端(terminal)的方式启动服务器,terminal除了上面的方法外,在pycharm内也有一个Terminal选项,在那里执行命令也可以。

屏幕快照 2018-01-10 13.54.17.png

然后还有关键的一点,在项目中找到setting.py,在里面的'ALLOWED_HOSTS = []'中添加本机的IP地址,如

ALLOWED_HOSTS = ['127.0.0.1',
                 '192.168.0.1']

本机IP地址在系统偏好设置-网络中看到。

现在,只要和本机在同一网络下的设备,都可以通过浏览器进入到我们的服务器中了。

尝试写一个接口

打开example目录下views.py文件,填写内容

from django.http import HttpResponse,JsonResponse

def hello(request):
    return HttpResponse('hello world')  //返回普通文本数据
    # return JsonResponse({'data':'response'})  //返回json格式数据

上面代码应该好理解,在执行hello函数的时候返回一段内容,其中如果需要返回json格式的内容,需要导入JsonResponse

然后在urls.py中添加

from django.conf.urls import url
from django.contrib import admin

import example.views as views  

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^helloworld/hello', views.hello),
]

import example.views as views 导入example的views文件,以views来命名
url(r'^helloworld/hello', views.hello) 新建一个接口为hello/hello的API,此时访问127.0.0.1:8000/helloworld/hello即可看到返回值

写一个get接口

然后就可以些多几个接口进行测试,现在尝试写一个get请求的接口,同样是在view文件里编写接口函数,然后在urls文件中定义接口路径

def get_test(request):
    if request.method == 'GET':
        return HttpResponse('接收到get请求')

    return HttpResponse('error')

urls.py文件

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^helloworld/hello', views.hello),
    url(r'^helloworld/get_test', views.get_test),
]

注意,urls.py中定义好接口路径,可能不会马上生效,如果发现接口无效,可以尝试重新开启服务器。

写一个post接口

位置还是一样

def post_test(request):
    if request.method == 'POST':
        title = request.POST.get('title','值为空时')
        return HttpResponse('接收到post请求,接收到值: ' + title)
    return HttpResponse('error')

url(r'^helloworld/post_test', views.post_test),

还记得上面提到的postman工具吗,我们在浏览器是没有办法测试post接口的,打开postman输入链接和带参,点击send即可发送post请求

屏幕快照 2018-01-10 14.57.29.png

如果post不成功,一是csrf错误,请参考该链接,解决办法是在setting.py文件里注释掉 MIDDLEWARE的'django.middleware.csrf.CsrfViewMiddleware'即可

尝试写一个聊天室

服务器有了,接口也会了,现在就要学习如何搭建一个聊天室进行聊天。聊天室的实现我是在该简书链接中学习的。

在setting的INSTALLED_APPS下添加'channels'。

如果是初次使用pycharm,可能会没有一些库,如channels等,这样在导入库的试试会出错,可以在Prederences-Project:helloworld-Project Interpreter中添加必须的库即可导入。

接着继续在setting中添加

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgiref.inmemory.ChannelLayer",
        'ROUTING': 'helloworld.routing.channel_routing',
    },
}

这样就配置好了通讯的通道

在example目录下新建consumers.py文件,内容为

from channels import Group
import json
from channels import channel_layers

def ws_connect(message):
    print('已连接客户端')
    Group('users').add(message.reply_channel)
    message.reply_channel.send({
        'text': json.dumps({
            'msg': u"你好,很高兴为你服务。",
            'talk': False
        })
    })

def ws_disconnect(message):
    print('与客户端断开连接')
    Group('users').discard(message.reply_channel)

def ws_receive(message):
    print('接收到客户端发来的消息')
    data = json.loads(message['text'])
    message.reply_channel.send({
        'text': json.dumps({
            'msg': u"我正在思考你的问题{%s}" % data["text"],
            'talk': True
        })
    })

这里是channels通讯的三个函数,连接客户端、断开客户端以及收到客户端发送的消息。

接着做一个HTML页面用于测试,在example目录下新建templates文件,在里面继续新建一个example的文件,在里面新建一个chat.html,内容如下

屏幕快照 2018-01-10 15.59.25.png
<!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>

在views中添加

def chat_page(request):
    return render(request, 'example/chat.html')

在urls中添加

url(r'^helloworld/chat_page', views.chat_page),

此时浏览器打开链接127.0.0.1:8000/helloworld/chat_page即可看到显示页面,尝试输入一些值

屏幕快照 2018-01-10 16.01.39.png

完成聊天室

由此就完成了聊天室的功能,现在解释一下刚刚的操作,我们在setting.py的INSTALLED_APPS中添加了channels,并且添加了CHANNEL_LAYERS配置通道路径,就是routing.py,routing里导入了consumers.py,我们在consumers里面就可以进行通讯的操作了,在views里我们添加了chat_page函数,该函数的作用是回调一个网页供浏览器展示。

在chat.html里有个路径,var socket = new WebSocket('ws://' + window.location.host + '/users/');因为channels是使用websocket进行通讯的,所以路径头为ws://,后面接的/users/可以修改,用于判断处理不同用户连接服务器,比如user1,那么在连接服务器的时候就会在consumers.ws_connect函数中获取到user1。

用户通讯目前的功能只是一个聊天室,且机器人的回复是message.reply_channel.send(),就是顺着该通道返回,这样并不能做到多人通讯。记得在ws_connect里的Group('users').add(message.reply_channel)吗,这里表示Group的名为'users'的组添加了该客户端的通道,可以看到在断开连接时ws_disconnect该组进行了对应通道的删除,我们可以通过这个功能进行双人通讯或群组通讯,只要根据上面的user1的方式进行匹配即可。

服务器进行iOS推送

所谓推送,可以是客户端正处于和服务器端的连接过程中,服务器通过建立的通讯管道进行消息推送,也可以是像微信那样,即便手机app被手动刷掉了,也能有一个消息弹窗,这里就说一下这种推送。

iOS有本地推送和网络推送,关于网络推送我之前有讲过,链接在这里,建议先看一下这篇文章,因为我们需要用到里面的推送证书,获取到证书之后还需要处理成pem格式,证书的获取和处理可以参考这篇文章

证书处理

从钥匙串中将推送证书导出来后为.p12文件,通过终端将其转换为pem格式,现将该p12文件放到桌面上,假设该.p12文件名为mycert.p12

$ cd desktop
$ openssl pkcs12 -in mycert.p12 -out MyApnsCert.pem -nodes

现在能在桌面上获取到MyApnsCert.pem文件,将该文件拖入到example目录下,这样证书处理就完成了

添加推送函数

还是在views.py上进行

首先需要导入一个库,如果没有就按我上面说的进行添加,这个库的github地址

from apns2.client import APNsClient
from apns2.payload import Payload
def push_ios(request):

    token_hex = 'device token'
    payload = Payload(alert="Hello World!", sound="default", badge=1)
    topic = 'your bundle identifier'
    client = APNsClient('example/MyApnsCert.pem', use_sandbox=True, use_alternative_port=False)
    client.send_notification(token_hex, payload, topic)
    return HttpResponse('response')

device token不用我说了吧,知道网络推送的就知道怎么获取,这个值一般是在客户端连接上服务器之后发送给服务器,以供服务器进行推送用,服务器存储这一块本文就不说了。

payload里面带的是内容,以json的格式发送,上面的数值在iOS设备上收到的内容格式为

    aps =     {
        alert = "Hello World!";
        badge = 1;
        sound = default;
    };

topic 为iOS app的bundle id
client创建时注意路径问题,如果路径不对是会报错的,参数use_sandbox指开发模式,该token是生产模式时则改成false

然后写好接口即可。

url(r'^helloworld/push_ios', views.push_ios),

调用后很快就能看到手机收到推送证书了。

结语

本文介绍了如何通过Django框架搭建一个后台,并且实现了聊天功能,支持双人聊天、群聊,以及对iOS设备的消息推送功能,每一个功能都花了我好多时间,写这篇文章可以帮助我梳理知识点,应该也能帮到需要的人。

相关文章

网友评论

      本文标题:mac使用Django搭建后台服务器并添加实时通讯功能

      本文链接:https://www.haomeiwen.com/subject/bnxonxtx.html