使用云信SDK构建自习室应用的后端开发
说明
萌新第一次接触这样的项目,有不足之处还请多谅解。
配套的客户端开发博客如下:
https://blog.csdn.net/erefas/article/details/117288577?spm=1001.2014.3001.5502
-
目的
配套客户端的应用需求,通过在后端维护和处理数据的方式,便于在客户端实现更强大的数据管理和调用功能。同时使前后端分离,解耦合,更便于应用在多平台的移植。
-
开发风格
使用restful风格的开发方式,后端给前端提供数据接口。前端调用接口,后端处理调用并响应,返回约定的json格式数据。
-
开发工具
应用服务器使用基于python的django开发框架,以便快捷地实现相应功能。使用python语言开发可以更方便地进行http请求,以便于云信SDK的调用。
-
服务器
该后端应用部署在云服务器上,运行于centos7.0系统上,需要对linux系统有一定的认识。
-
个人说明
这里的后端服务器尚处于十分简陋的状态,只完成了基础的内容,没有达到企业级的使用需求,仅供学习和参考。
简单的模型和接口设计
模型设计
-
房间
- 房间id:是创建房间时云信服务器所给的房间唯一标识,用于云信客户端的调用,同时也将其作为数据库中主键。
- 房间名:房间基础信息,创建房间时必须且唯一的属性值。
- 房主用户名:当前房间的房主用户名。
- 房间标签:房间的标签,默认值为空。
- 房间大小:房间可容纳人数,默认为4。
- 活动状态:如果房间内有用户在使用,则房间为活动状态,否则房间为停止状态,房间一旦进入停止状态就会被删除。创建后默认为停止状态,当有用户进入时房间便激活。
-
用户
- 用户id:数据库在用户数据的主键,用于云信客户端的房间与用户关联。
- 用户名:用户的唯一标识,由服务器进行维护,同时在注册是需要传递给云信服务器。
- 用户密码:用户的登录密码,由服务器进行维护。
- 用户昵称:用户对外显示的昵称,默认为用户名。
- 用户token:由云信服务器给定的登录云信客户端的token信息,在注册用户时由云信服务器对每一个用户名进行分配。
接口设计
api统一由以下json格式返回数据
{
"code": 0, //返回的状态码,0为成功,1为失败。
"desc": "aaa", //返回信息的状态描述。
"data": datas, //返回的数据,根据不同的api,内容也不一样。
}
应用服务器的搭建
-
django的使用
推荐访问django的官网文档,有中文翻译,内容十分详细。
-
模型对象
创建2个django应用如下:
一个是room的服务应用,一个是user的服务应用。
然后构建room和user的模型:
#room_server/models.py from django.db import models class Room(models.Model): rid = models.BigIntegerField(primary_key=True) name = models.CharField(max_length=32, unique=True) owner = models.CharField(max_length=16) size = models.IntegerField(default=4) is_active = models.BooleanField(default=False) tag = models.CharField(max_length=32,default='无') #user_server/models.py from django.db import models class User(models.Model): uid = models.BigAutoField(primary_key=True) username = models.CharField(max_length=16,unique=True) passwd = models.CharField(max_length=32) nickname = models.CharField(max_length=32) token = models.CharField(max_length=64) #一个user对应一个room,user直接通过user.room获得room数据,room通过room.user_set来获得一个user的QuerySet #设置的外键,这里的on_delete策略选择SET_NULL,当房间被删除时设置为空。 room = models.ForeignKey('room_server.Room',on_delete=models.SET_NULL,null=True)
-
工具类
由于在处理请求时,服务器需要通过requests访问云信服务器,所以将访问云信服务器的相关调用放在工具类里。
新建包utils,
首先是util.py,访问云信服务器需要配置请求头,以下是代码:
#utils/util.py import hashlib import random import time def __checkSumBuilder(appSecret, nonce, curTime): string: str = appSecret + nonce + curTime sha1 = hashlib.sha1(string.encode('utf-8')) return sha1.hexdigest() def get_headers(appkey): appSecret = 'xxxxxxx' #你的云信服务密码 nonce = str(random.randint(0, 65535)) curTime = str(int(time.time())) checkSum = __checkSumBuilder(appSecret, nonce, curTime) headers = { 'AppKey': appkey, 'Nonce': nonce, 'CurTime': curTime, 'CheckSum': checkSum, 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } return headers
然后是房间和用户服务的requests请求
#user_request.py import json import requests from utils.util import get_headers #由于对云信服务器响应状态码的处理 def __get_result(status_code): result = { } if status_code == 200: result['desc'] = '操作成功' result['state'] = True elif status_code == 315: result['desc'] = 'IP限制' result['state'] = False elif status_code == 405: result['desc'] = '参数长度过长' result['state'] = False elif status_code == 414: result['desc'] = '云信参数错误' result['state'] = False elif status_code == 500: result['desc'] = '服务器内部错误' result['state'] = False elif status_code == 503: result['desc'] = '服务器繁忙' result['state'] = False else: result['desc'] = '未知错误' result['state'] = False return result #注册请求 def register_request(app_key,data): url = 'https://api.netease.im/nimserver/user/create.action' headers = get_headers(app_key) resp = requests.post(url=url,headers=headers,data=data) resp_body = json.loads(resp.text) result = __get_result(resp_body['code']) #如果响应成功,将数据放入(后面格式基本同理) if result['state'] == True: result['data'] = resp_body['info'] return result
#utils/room_request.py from utils.util import get_headers import requests import json def __get_result(status_code): result = { } if status_code == 200: result['desc'] = '操作成功' result['state'] = True elif status_code == 400: result['desc'] = '请求不是一个合法的json' result['state'] = False elif status_code == 401: result['desc'] = 'appKey错误' result['state'] = False elif status_code == 403: result['desc'] = '非法操作或没有权限' result['state'] = False elif status_code == 404: result['desc'] = '对象不存在' result['state'] = False elif status_code == 414: result['desc'] = '云信访问参数错误' result['state'] = False elif status_code == 417: result['desc'