Linux服务器项目-共享单车

Linux服务器项目-共享单车

一、应用层协议设计

  • 通信双方交换数据的格式与顺序
  • 通信双方应该采取的动作
  • 使用 protobuf 序列化
  1. 短信获取

获取短信请求:mobile_resquest

字段名 类型 属性 描述
mobile string required 手机号码,必须为大陆手机号。取11位数字

获取短信响应:mobile_response

字段名 类型 属性 描述
code int32 required 响应代号:200表示成功。400表示失败。
icode int32 required 验证码
desc string optional 失败时描述原因(可选)
  1. 登录验证

登录请求:login_request

字段名 类型 属性 描述
mobile string required 手机号码,必须为大陆手机号。取11位数字
icode int32 required 验证码

登录响应:login_response

字段名 类型 属性 描述
code int32 required 响应代号:200表示成功。400表示失败。
desc string optional 失败时描述失败原因(可选)
  1. 充值

充值请求:recharge_request

字段名 类型 属性 描述
mobile string required 手机号码,必须为大陆手机号。取11位数字
amount int32 required 充值数量

充值响应:recharge_response

字段名 类型 属性 描述
code int32 required 响应代号:200表示成功。400表示失败。
desc string optional 失败时描述失败原因(可选)
balance int32 required 最新余额
  1. 查询余额

查询余额请求:account_balance_request

字段名 类型 属性 描述
mobile string required 手机号码,必须为大陆手机号。取11位数字

余额查询响应:account_balance_response

字段名 类型 属性 描述
code int32 required 响应代号:200表示成功。400表示失败。
desc string optional 失败时描述失败原因(可选)
balance int32 required 余额(失败时置为-1)
  1. 查询充值记录

充值记录查询请求:list_account_records_request

字段名 类型 属性 描述
mobile string required 手机号码,必须为大陆手机号。取11位数字

充值记录查询请求:list_account_records_response

字段名 类型 属性 描述
code int32 required 响应代号:200表示成功。400表示失败。
desc string optional 失败时描述失败原因(可选)
records account_record repeated 类型见下表
account_record
字段名 类型 属性 描述
type int32 required 0 : 骑行消费, 1 : 充值, 2 : 退款
limit int32 required 消费或者充值金额
timestamp uint64 repeated 记录发生时的时间戳
  1. 骑行记录查询

骑行记录查询请求:list_travel_records_request

字段名 类型 属性 描述
mobile string required 手机号码,必须为大陆手机号。取11位数字

骑行记录查询响应: list_travel_records_response

字段名 类型 属性 描述
code int32 required 响应代号:200表示成功。400表示失败。
desc string optional 失败时描述失败原因(可选)
records travel_record repeated 类型见下表
mileage double required 骑行里程
discharge double required 排放
calorie double required 卡路里
travel_record
字段名 类型 属性 描述
stm uint64 required 开始骑行时的事件戳
duration int32 required 骑行时长
amount uint32 repeated amount

二、使用 protobuf 将如上协议结构化数据

protobuf的使用参考:谷歌protobuf(Protocol buffers)的使用
proto源码如下:

syntax = "proto2";

package shared_bike;

message mobile_request {
    required string mobile = 1;
}

message mobile_response {
    required int32 code   = 1;   //响应代号
    required int32 icode  = 2;   //验证码
    optional string data  = 3;   //失败原因
}


message login_request {
    required string mobile  = 1;    // 手机号码
    required int32  icode   = 2;    // 验证码
}


message login_response {
    required int32   code   = 1;    // 响应代号
    optional string  desc   = 2;    // 验证码
}

message recharge_request {
    required string mobile  = 1;    // 手机号码
    required int32  amount  = 2;    // 充值金额
}


message recharge_response {
    required int32   code   = 1;    // 响应代号
    optional string  desc   = 2;    // 验证码
    required int32  balance = 3;    // 最新的余额
}

message account_balance_request {
    required string mobile = 1;
}

message account_balance_response {
    required int32   code   = 1;    // 响应代号
    optional string  desc   = 2;    // 验证码
    required int32  balance = 3;
}

message list_account_records_request {
    required string mobile = 1;
}

message list_account_records_response {
    required int32   code   = 1;    // 响应代号
    optional string  desc   = 2;    // 验证码
    message account_record {
        required int32  type      = 1; // 0 : 骑行消费,  1 : 充值, 2 : 退款
        required int32  limit     = 2; // 消费或者充值金额
        required uint64 timestamp = 3; // 记录发生时的时间戳
    }

    repeated account_record records = 3;
}

message list_travel_records_request {
    required string mobile = 1;
}

message list_travel_records_response {
    required int32   code   = 1;    // 响应代号
    optional string  desc   = 2;    // 验证码
    message travel_record {
        required uint64 stm      = 1;   // start timestamp
        required uint32 duration = 2;   // 骑行时长
        required uint32 amount   = 3;   // 所耗金额
    }

    required double              mileage   = 3; // 里程
    required double              discharge = 4; // 排放
    required double              calorie   = 5; // 卡路里
    repeated travel_record       records   = 6;
}

三、开发工具:Visual Studio 2019

VS2019下写Linux代码参考:使用 Visual Studio 2019 开发 Linux 项目

四、第一次迭代

1. 目标

实现libevent 和线程池的整合,结合发布订阅者模式实现业务逻辑层的代码框架,能够实现获取短信请求的模拟响应(不包含数据库的具体实现)。
Linux服务器项目-共享单车

2. 设计类图

Linux服务器项目-共享单车

  • NetworkInterface - 负责监听 tcp连接、接收和响应客户端请求数据,其通过调用 DispatchMsgService类的相关接口解析消息和事件,并派发事件。
  • DispatchMsgService - 负责分发消息服务模块,其实就是把外部收到的消息,转化成内部事件,也就是data->msg->event的解码过程,然后再把事件投递至线程池的消息队列,由线程池调用其process 方法对事件进行处理,最终调用每个event的handler方法来处理event,此时每个event handler需要subscribe该event后才会被调用到。
  • thread_pool_t - 线程池,实现高并发处理各种事件(用户、单车事件)。
  • iEventHandler - 负责处理相关的事件(如:用户、单车事件等)。
  • iEvent - 请求事件实体。

3. 第一次迭代源码

链接( 密码:shared):共享单车项目第一次迭代源码

五、第二次迭代

1. 目标

实现后台数据库访问模块的框架,能够实现验证请求并响应(支持数据库操作)

2. 设计类图

Linux服务器项目-共享单车

  • MysqlConnection - 数据库访问接口
  • SqlTables - 负责数据库表的创建
  • BusinessProcessor - 负责协调处理事务

3. 数据库表设计

  1. 用户信息
表名:userinfo
字段名 类型 是否为空 默认值 主、外键 备注
id int(16) NOT 1, 自增长 PK 用户ID
username varchar(128) NOT 用户名:英文字符、数字和特殊符号的组合
mobile varchar(16) NOT ‘13000000000’ 手机号
registertm timestamp NOT 当前时间 注册时间
money int(4) NOT 0 账户余额

表其他信息:

名称 类型 备注
mobile_index(mobile) index 索引
  1. 自行车信息
表名:bikeinfo
字段名 类型 是否为空 默认值 主、外键 备注
id int NOT 自增长 PK 单车ID
devno int NOT 单车编号
status tinyint(1) NOT 0 单车状态:0(停止)、1(骑行中)、2(损坏)、3(维修中)
trouble int NOT 0 损坏类型编号
tmsg varchar(256) NOT “” 损坏原因描述
latitude double(10,6) NOT 0 纬度
longitude double(10,6) NOT 0 经度

表其他信息:

名称 类型 备注
unique(devno) PRIMARY KEY 唯一键约束

4. 第二次迭代源码

链接( 密码:shared):共享单车项目第二次迭代源码

上一篇:表单的required 属性


下一篇:CacheHelper