状态机与业务逻辑
司机状态机与业务逻辑
状态机在业务逻辑中用status表示,事实上,只存在于web和前端交互的业务逻辑中,而不会影响到存储服务器,而status的改变操作也都是在前端完成的
IDLE
IDLE状态的司机代表是空闲状态
- 司机端不做任何处理会一直处于这个状态
- 司机端每隔2s向前端更新自己的定位信息,但是不会有后台服务器不会由记录,会不断更新sessionid的生命周期,
READY
READY状态的转变是司机点击”开始接单”,status由IDLE变为READY,页面按钮变为“停止接单”
- 司机端每隔两秒调用底层JNI模块更新自己定位信息(向缓存中的GEO司机坐标池),协议数据包括sessionid,status,driver,位置信息
- 有用户下单并且选中该司机,返回数据中会携带有orderid字段不为空且status字段为READY,就会弹窗提示司机是否接单
- 司机如果拒绝接单,那么会将status改为IDLE,并将自己从GEO坐标池删除,然后重复IDLE逻辑
- 司机如果点击“停止接单”,会将status改为IDLE,并将自己从GEO坐标池删除,然后重复IDLE逻辑
CATCHING
司机选择接单后会将status改为CATCHING,且“停止接单” 变为“乘客上车”
- 司机端每隔2s调用底层JNI模块更新自己的定位信息(包括sessionid,status,driver,位置信息),此时会将这些数据更新再缓存中的临时订单表中
- 响应数据有从缓存中临时订单表表中拿到乘客坐标,司机端会显示再Android上
DRIVING
司机接到乘客后,点击“”乘客上车“,status改为DRINVING,"乘客上车"变为”订单结束”
- 司机端每隔2s向调用底层JNI模块更新自己的定位信息包括sessionid,status,driver,位置信息),此时会将这些数据更新再缓存中的临时订单表中
- 响应数据会拿到乘客的坐标更新在Android上
- 乘客到达目的地后,乘客点击“订单结束”,status变为“IDLE”重复IDLE逻辑,
乘客业务逻辑
IDLE
- 表示乘客已经登陆但是未约车,每隔2s调用底层JNI模块,更新缓存中地理位置信息,以及更新自己的sessionid
- 乘客在Android 搜索栏输入目的地,在热点搜索栏确定地址后,调用了底层JNI模块更新了自己的状态信息,会请求缓存从GEO坐标池中拿出以乘客经纬度为中心radius范围内的一组司机信息,以数组的形式drivers[] (里面是司机的sessionid,经纬度,与乘客距离,),返回给前端Android
-乘客选择司机后点击”下单“,等待司机接单,
WAITING
-
司机接单后更改status为”WAITING“,”下单“变成”等待司机“
-
每隔2s用底层JNI模块,更新缓存中地理位置信息,以及更新自己的sessionid
-
响应数据中拿到司机的经纬度,更新在Android上
TRAVELLING
-
在司机端点击”乘客上车“,乘客status更改为TRAVELLING,
-
每隔2s用底层JNI模块,更新缓存中地理位置信息,以及更新自己的sessionid
-
响应数据中拿到司机的经纬度,更新在Android上
注意
响应数据中一直都有的字段result(请求成功与否),recode(用来定位错误打印信息),status,orderid这个两个最重要的字段时前端业务逻辑的核心
- 一旦有用户下单时,服务器通过GEO坐标池查找出最radius范围内的一个drivers[],
业务逻辑流程图
登陆业务
- 前端将username,password,driver发送给web服务器,web请求存储服务器根据用户名密码(MD5加密)查库,web接收“ok”包,web生成sessionid,向存储服务器发起redis生成哈希表操作(sessionid为Key,username,orderid为域)
- web接收“ok”包更新sessionid的生命周期(setlifecycle)
- web接收“ok”包将sessionid返回前端
注册业务
- 前端将注册信息发送给web,web将密码md5加密后向存储服务器发起persisitent请求,MySQL插入用户表,web收到“ok”包,生成sessionid并向存储服务器发起cache请求,建立乘客(司机)临时信息映射表(sessionid为Key,username,orderid为field)
- web拿到“ok”包发起cache请求更新sessionid生命周期,拿到“ok”包后将session封装返回前端Android
司机地理位置更新业务流程
-
司机点击“开始接单”, 更新status为“ready”,每隔2s发送坐标调用地理位置JNI模块向web发起locationChanged请求;
-
司机点击“接收订单”, 更新status为“catching”,每隔2s发送坐标调用地理位置JNI模块向web发起locationChanged请求
-
司机点击“停止接单”, 更新status为“idle”,开始idle业务逻辑
-
司机点击“乘客已上车”, 更新status为“driving”,每隔2s发送坐标调用地理位置JNI模块向web发起locationChanged请求
-
司机点击“订单完成”, 更新status为“idle”,开始idle逻辑
-
web处理逻辑
-
web先判断sessionid是否存在,不存在(过期)返回前端跳转到登陆界面提示重新登陆;否则更新sessionid,拿到orderid和status
-
status为idle,将自己从坐标池摘除的缓存操作,返回json
-
status为ready,先将司机的信息从坐标池山吃,web拿到ok包,在将司机的信息添加到坐标池,拿到结果返回json,此时orderid为可能为空或非空(因为可能在这个过程,也可能在2s过程已经乘客下单把orderid设置进来了)返回前端,前端解析到orderid为空,不作为;不为空,此时提醒司机是否接单
-
status为catching,将自己从坐标池摘除,在临时订单表中更新司机自己的位置,根据临时订单表查询乘客的位置,返回前端
-
status为driving,将自己从坐标池摘除,根据临时订单表查询乘客的坐标,返回给前端,此时前端判断status为driving但是orderid为“NONE”,则会将司机UI"订单完成"置为“开始接单”,status置为idle,因为这代表是乘客已经下车但是司机未点击订单完成操作
-
乘客地理位置更新业务流程
- 乘客未作任何操作,status为“idle”,每隔2s发送坐标调用更新地理位置JNI模块
- 乘客因为司机操作,status变为“travelling”,每隔2s发送坐标调用更新地理位置JNI模块
- 乘客因为司机操作,status变为“waiting”,每隔2s发送坐标调用更新地理位置JNI模块
- web服务器处理逻辑
- web先判断sessionid是否存在,不存在(过期)返回前端跳转到登陆界面提示重新登陆;否则更新sessionid,拿到orderid和status
- status为“idle“,会发起缓存请求查询以乘客坐标方圆radius范围内的状态为”ready“的司机(司机临时信息映射表)封装成数组返回给前端;注意如果此时status为IDLE,但是orderid不为空(存在在2s内status为idle但是司机点击了接单生成了orderid置入)
- status为“waiting“缓存请求向临时订单表更新自己的坐标,缓存请求拿到临时订单表中的司机坐标返回前端
- status为“travelling”缓存请求向临时订单表更新自己的坐标,缓存请求拿到临时订单表中的司机坐标返回前端,返回前端的json解析时如果status为travelling,但是orderid为“none”则置status为idle说明订单已经结束了
乘客下单流程
-
乘客在UI界面,以乘客当前定位为中心展示地图,乘客输入地址热点搜索,显示司机列表,点击“约车”,调用提交订单JNI模块
-
web服务器模块,web先判断sessionid是否存在,不存在(过期)返回前端跳转到登陆界面提示重新登陆;否则更新sessionid,
- web发起缓存请求(rediusGEO)拿到附近司机列表,然后制定最近的一名司机,取出其sessionid,联合乘客的sessionid,在缓存中建立临时订单表
- 给司机sesiionid和乘客sessionid添加orderid字段,再将操作结果返回给前端
司机完成订单流程
-
司机点击“订单完成”,调用完成订单JNI模块,
-
web服务器web先判断sessionid是否存在,不存在(过期)返回前端跳转到登陆界面提示重新登陆;否则更新sessionid,
- 拿到orderid,缓存操作拿到临时订单表,持久操作操作MySQL创建永久订单表,从临时订单表拿到乘客sessionid并将缓存中的session的orderid置为“NONE”
- 将缓存中司机本身的sessionid对应的orderid置为“NONE”
- 删除临时订单表,操作结果返回前端