山东大学软件学院创新实训——飞讯(四)
目录
一.目标概述
二.腾讯云im第三方回调
二.回调分类
三.回调示例
1.请求url
2.请求包示例
3.应答包示例
四.回调的保存
1.分析
2.实体类
3.controller层
4.service层
5.dao层
6.xml数据库操作
五.工具类ResCondition
六.总结
一.目标概述
我们的项目——飞讯采用基于腾讯云im的框架进行搭建,作为服务端,需要将与im进行交互的数据保存至本地服务器中,因此,需要采用回调的方式进行数据的保存。
因此,本次的目标是理解腾讯云im的回调原理,并且通过保存登录注册的回调信息进行试验,从而验证回调的成功,从而为后续聊天、好友、群等功能的回调进行记录。
二.腾讯云im第三方回调
所谓回调,即即时通信 IM 后台会在某一事件发生之前或者之后,向 App 的后台服务器发送请求,App 后台可以据此进行必要的数据同步,或者干预事件的后续处理流程。
第三方回调将通过 HTTP/HTTPS 请求的方式发送给 App 后台服务器,App 后台服务器需要处理即时通信 IM 的回调请求并尽快进行应答。以群内发言之前回调为例,即时通信 IM 后台会在下发该消息之前回调 App 后台服务器,并根据回调结果决定该消息是否应当下发,App 不仅可以基于该回调来实现消息同步,而且可以进行发消息安全打击。回调业务流程如下图所示:
二.回调分类
从功能角度来看,回调可以分为四大类:
- 在线状态回调
- 资料关系链回调
- 单聊消息回调
- 群组系统回调
从处理角度来看,回调可以分为以下两大类:
- 事件发生之前回调:回调的主要目的在于让 App 后台可以干预该事件的处理逻辑,即时通信 IM 会根据回调返回码确定后续处理流程(例如发送群消息之前回调)。
- 事件发生之后通知:回调的主要目的在于让 App 后台实现必要的数据同步,即时通信 IM 忽略回调返回码(例如群组成员退群之后通知)。
三.回调示例
1.请求url
https://www.example.com?SdkAppid=$SDKAppID&CallbackCommand=$CallbackCommand&contenttype=json&ClientIP=$ClientIP&OptPlatform=$OptPlatform
请求参数说明
参数 | 说明 |
---|---|
https | 请求协议为 HTTPS,请求方式为 POST |
www.example.com | 回调 URL |
SdkAppid | 创建应用时在即时通信 IM 控制台分配的 SDKAppID |
CallbackCommand | 固定为:State.StateChange |
contenttype | 固定值为 JSON |
ClientIP | 客户端 IP,格式如:127.0.0.1 |
OptPlatform | 客户端平台,取值参见 第三方回调简介:回调协议 中 OptPlatform 的参数含义 |
2.请求包示例
{"CallbackCommand": "State.StateChange","EventTime": 1629883332497,"Info": {"Action": "Login","To_Account": "testuser316","Reason": "Register"},"KickedDevice": [{"Platform": "Windows"},{"Platform": "Android"}]
}
请求包字段说明
字段 | 类型 | 说明 |
---|---|---|
CallbackCommand | String | 回调命令 |
Info | Object | 用户上下线的信息 |
Action | String | 用户上线或者下线的动作,Login 表示上线(TCP 建立),Logout 表示下线(TCP 断开),Disconnect 表示网络断开(TCP 断开) |
To_Account | String | 用户 UserID |
Reason | String |
用户上下线触发的原因:
|
KickedDevice | Array | 如果本次状态变更为 Login(Register),而且有其他设备被踢下线,才会有此字段。此字段表示其他被踢下线的设备的信息。 |
KickedDevice.Platform | String | 被踢下线的设备的平台类型,可能的取值有"iOS", "Android", "Web", "Windows", "iPad", "Mac", "Linux"。 |
EventTime | Integer | 触发本次回调的时间戳,单位为毫秒。 |
3.应答包示例
{"ActionStatus": "OK","ErrorCode": 0,"ErrorInfo": ""
}
应答包字段说明
字段 | 类型 | 属性 | 说明 |
---|---|---|---|
ActionStatus | String | 必填 | 请求处理的结果,OK 表示处理成功,FAIL 表示失败 |
ErrorCode | Integer | 必填 | 错误码,0表示 App 后台处理成功,1表示 App 后台处理失败 |
ErrorInfo | String | 必填 | 错误信息 |
四.回调的保存
1.分析
可以看出,腾讯云im的回调采用json的形式进行传送,当用户执行相应的操作时,腾讯云im会将用户执行的操作以json的形式回调给本地服务器,当开启了本地服务器的回调端口后,便可以接收回调的json,进行保存。
此处,我采用fastjson对回调的json进行解析,获取相应的参数,封装到实体类中,从而向数据库进行保存。
2.实体类
以登录登出的状态变化为例:
package com.feixun.feixunshiyan.domain.imCallBack;import java.sql.Timestamp;public class StateChange {private String clientIP;private Timestamp eventTime;private String action;private String to_Account;private String reason;public StateChange(String clientIP, Timestamp eventTime, String action, String to_Account, String reason) {this.clientIP = clientIP;this.eventTime = eventTime;this.action = action;this.to_Account = to_Account;this.reason = reason;}public String getClientIP() {return clientIP;}public void setClientIP(String clientIP) {this.clientIP = clientIP;}public Timestamp getEventTime() {return eventTime;}public void setEventTime(Timestamp eventTime) {this.eventTime = eventTime;}public String getAction() {return action;}public void setAction(String action) {this.action = action;}public String getTo_Account() {return to_Account;}public void setTo_Account(String to_Account) {this.to_Account = to_Account;}public String getReason() {return reason;}public void setReason(String reason) {this.reason = reason;}@Overridepublic String toString() {return "StateChange{" +"clientIP='" + clientIP + '\'' +", eventTime=" + eventTime +", action='" + action + '\'' +", to_Account='" + to_Account + '\'' +", reason='" + reason + '\'' +'}';}
}
3.controller层
@RequestMapping("/imCallBack")@ResponseBodypublic Map<String, Object> imCallBack(@RequestParam Map<String,String> headMap, @RequestBody Map<String,Object> bodyMap){Map<String,Object> responseMap = new HashMap<>(3);if (!bodyMap.containsKey("CallbackCommand")){responseMap.put("ActionStatus","FAIL");responseMap.put("ErrorCode",1);responseMap.put("ErrorInfo","json中不存在CallbackCommand字段");return responseMap;}String callbackCommand = (String) bodyMap.get("CallbackCommand");if (callbackCommand.equals("State.StateChange")){String headStr = JSON.toJSONString(headMap);String bodyStr = JSON.toJSONString(bodyMap);JSONObject headJson = JSONObject.parseObject(headStr);JSONObject bodyJson = JSONObject.parseObject(bodyStr);String clientIP = headJson.getString("ClientIP");Timestamp eventTime = bodyJson.getTimestamp("EventTime");JSONObject Info = bodyJson.getJSONObject("Info");String action = Info.getString("Action");String to_Account = Info.getString("To_Account");String reason = Info.getString("Reason");//System.out.println(headJson);//System.out.println(bodyJson);//System.out.println(callbackCommand + "" +clientIP + " " + eventTime + " " + action + " " + to_Account + " " + reason);StateChange stateChange = new StateChange(clientIP,eventTime,action,to_Account,reason);int res = callBackService.stateChange(stateChange);if (res == ResCondition.stateChange_success){responseMap.put("ActionStatus","OK");responseMap.put("ErrorCode",0);responseMap.put("ErrorInfo","");return responseMap;}
4.service层
service接口:
public int stateChange(StateChange stateChange);
service实现:
@Service
public class CallBackServiceImpl implements CallBackService {@Autowiredprivate CallBackMapper callBackMapper;@Overridepublic int stateChange(StateChange stateChange) {int success = callBackMapper.stateChange(stateChange);if (success > 0){return ResCondition.stateChange_success;}else {return ResCondition.stateChange_fail;}}
5.dao层
@Mapper
@Repository
public interface CallBackMapper {public int stateChange(StateChange stateChange);
6.xml数据库操作
<insert id="stateChange" parameterType="StateChange">insert into stateChange(clientIP,eventTime,action,to_Account,reason) values (#{clientIP},#{eventTime},#{action},#{to_Account},#{reason})</insert>
五.工具类ResCondition
由于不同的回调会产生不同的结果,如何区分这些结果,我采用了工具类进行区分,分别标记不同的状态,工具类如下:
public class ResCondition {public static int register_success = 1;public static int register_existed = -2;public static int register_fail = -1;public static int stateChange_success = 1;public static int stateChange_fail = -1;
六.总结
通过对im回调的学习,我明白了im回调的形式,同时学会了使用fastjson工具解析im回调的json包,从而将其加载进实体类中,进而保存到数据库,从而实现对im交互数据的保存。
山东大学软件学院创新实训——飞讯(四)相关推荐
- 山东大学软件学院创新实训——飞讯(一)
目录 一.项目介绍 二.docker的安装 1.服务器的配置 2.安装需要的包 3.添加GPG密匙,并添加Docker-ce软件源 4.安装Docker-ce 5.测试运行 6.添加当前用户到 doc ...
- 山东大学软件学院创新实训——飞讯(六)
目录 一.突如起来的变化及内部调整 二.uni-app的学习 三.uni-app的搭建 登录界面 (1)界面设计 (2)核心代码 注册界面 (1)界面设计 (2)核心代码 四.总结 一.突如起来的变化 ...
- 山东大学软件学院创新实训——飞讯(八)
目录 一.目标概述 二.功能设计与实现 搜索好友 (1)界面设计 (2)功能实现 消息发送组件 (1)发送消息界面概览 (2)功能实现 三.总结 一.目标概述 经过前面对uniapp的学习和飞讯项目的 ...
- 山东大学软件学院创新实训——飞讯(十二)
目录 一.目标概述 二.功能设计与实现 问卷首页 (1)界面设计 (2)功能实现 问卷详情页 (1)界面设计 (2)功能实现 问卷二维码 (1)界面设计 (2)功能实现 回答详情 (1)界面设计 (2 ...
- 山东大学软件学院创新实训——飞讯(二)
目录 一.后端框架-springboot 二.springboot项目的创建 1.启动idea,依次选择File -->> New -->> project,弹出下框 编辑2 ...
- 山东大学软件学院创新实训——飞讯(十三)
目录 一.目标概述 二.功能代码 1.问卷的创建 2.问题的回答 三.界面展示 四.总结 一.目标概述 这次项目完成的功能是问卷的创建和回答部分,我负责后端的编写,另外一位同学负责前端的编写,从而完成 ...
- 山东大学软件学院创新实训——飞讯(十一)
目录 一.目标概述 二.数据库设计 三.功能代码 1.工作日志的查询和展示 2.工作日志的添加 3.工作日志的修改 4.工作日志的删除 三.前后端联调后界面展示 四.总结 一.目标概述 本次项目实施的 ...
- 山东大学软件学院创新实训——飞讯(十)
目录 一.目标概述 二.功能设计与实现 1.配置配置文件 2.编写后端代码 3.前端代码 三.总结 一.目标概述 这一次项目实施的目的是实现图片的上传和url的生成,因此,主要是前端上传图片代码和后端 ...
- 山东大学软件学院创新实训——飞讯(九)
目录 一.内部又一次调整 二.目标概述 三.功能设计与实现 界面设计 功能实现 三.总结 一.内部又一次调整 今天,组内的又一名同学决定退群,此时,我们组内已经退了两名成员,因此,任务越来越紧迫,我们 ...
最新文章
- z17刷机miui12教程_《蝙蝠侠3百度影音》
- Docker系列之AspNetCore Runtime VS .NetCore Runtime VS SDK(四)
- HTTP面试题 ——TCP
- Learning to Rank入门小结 + 漫谈
- HTML 内容不能被选择,不能被复制
- 浅谈抖音下拉词框优化推广的优势
- Bootstrap 模态框(Modal)
- mac上设置sudo不要密码
- 自考《软件工程》总结笔记
- java写的小米商城_开发”小米商城官网首页”(静态页面)
- html5 调用摄像头 支持IE,ie调用不了摄像头 为什么电脑IE浏览器无法启动摄像头...
- GMT格林威治时间标准时北京时间
- L1 和 L2的区别
- 汉罗塔汉洛塔c++,看不懂ni打我
- 一刀工具箱- 语音合成工具
- java 基础:方法/函数
- “阳”后第1 2 3 4 5 6 7天的症状详解
- CentOS 安装HTTP代理服务器Tinyproxy---配置简捷
- 海康 大华 华为 宇视等安防摄像头、NVR、平台网关通过GB28181接入LiveGBS流媒体服务实现WEB无插件直播
- 基于磁链模型的非线性观测器