目录

一.目标概述

二.腾讯云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 用户上下线触发的原因:

  • Login 的原因有 Register:App TCP 连接建立或断网重连
  • Logout 的原因有 Unregister:App 用户注销帐号导致 TCP 断开
  • Disconnect 的原因有 LinkClose:即时通信 IM 检测到 App TCP 连接断开(例如 kill App,客户端发出 TCP 的 FIN 包或 RST 包);TimeOut:即时通信 IM 检测到 App 心跳包超时,认为 TCP 已断开(例如客户端网络异常断开,未发出 TCP 的 FIN 包或 RST 包,也无法发送心跳包)。心跳超时时间为400秒
  • 各种具体场景触发的回调 Reason 请参考 可能触发该回调的场景
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交互数据的保存。

山东大学软件学院创新实训——飞讯(四)相关推荐

  1. 山东大学软件学院创新实训——飞讯(一)

    目录 一.项目介绍 二.docker的安装 1.服务器的配置 2.安装需要的包 3.添加GPG密匙,并添加Docker-ce软件源 4.安装Docker-ce 5.测试运行 6.添加当前用户到 doc ...

  2. 山东大学软件学院创新实训——飞讯(六)

    目录 一.突如起来的变化及内部调整 二.uni-app的学习 三.uni-app的搭建 登录界面 (1)界面设计 (2)核心代码 注册界面 (1)界面设计 (2)核心代码 四.总结 一.突如起来的变化 ...

  3. 山东大学软件学院创新实训——飞讯(八)

    目录 一.目标概述 二.功能设计与实现 搜索好友 (1)界面设计 (2)功能实现 消息发送组件 (1)发送消息界面概览 (2)功能实现 三.总结 一.目标概述 经过前面对uniapp的学习和飞讯项目的 ...

  4. 山东大学软件学院创新实训——飞讯(十二)

    目录 一.目标概述 二.功能设计与实现 问卷首页 (1)界面设计 (2)功能实现 问卷详情页 (1)界面设计 (2)功能实现 问卷二维码 (1)界面设计 (2)功能实现 回答详情 (1)界面设计 (2 ...

  5. 山东大学软件学院创新实训——飞讯(二)

    目录 一.后端框架-springboot 二.springboot项目的创建 1.启动idea,依次选择File -->> New -->> project,弹出下框 ​编辑2 ...

  6. 山东大学软件学院创新实训——飞讯(十三)

    目录 一.目标概述 二.功能代码 1.问卷的创建 2.问题的回答 三.界面展示 四.总结 一.目标概述 这次项目完成的功能是问卷的创建和回答部分,我负责后端的编写,另外一位同学负责前端的编写,从而完成 ...

  7. 山东大学软件学院创新实训——飞讯(十一)

    目录 一.目标概述 二.数据库设计 三.功能代码 1.工作日志的查询和展示 2.工作日志的添加 3.工作日志的修改 4.工作日志的删除 三.前后端联调后界面展示 四.总结 一.目标概述 本次项目实施的 ...

  8. 山东大学软件学院创新实训——飞讯(十)

    目录 一.目标概述 二.功能设计与实现 1.配置配置文件 2.编写后端代码 3.前端代码 三.总结 一.目标概述 这一次项目实施的目的是实现图片的上传和url的生成,因此,主要是前端上传图片代码和后端 ...

  9. 山东大学软件学院创新实训——飞讯(九)

    目录 一.内部又一次调整 二.目标概述 三.功能设计与实现 界面设计 功能实现 三.总结 一.内部又一次调整 今天,组内的又一名同学决定退群,此时,我们组内已经退了两名成员,因此,任务越来越紧迫,我们 ...

最新文章

  1. z17刷机miui12教程_《蝙蝠侠3百度影音》
  2. Docker系列之AspNetCore Runtime VS .NetCore Runtime VS SDK(四)
  3. HTTP面试题 ——TCP
  4. Learning to Rank入门小结 + 漫谈
  5. HTML 内容不能被选择,不能被复制
  6. 浅谈抖音下拉词框优化推广的优势
  7. Bootstrap 模态框(Modal)
  8. mac上设置sudo不要密码
  9. 自考《软件工程》总结笔记
  10. java写的小米商城_开发”小米商城官网首页”(静态页面)
  11. html5 调用摄像头 支持IE,ie调用不了摄像头 为什么电脑IE浏览器无法启动摄像头...
  12. GMT格林威治时间标准时北京时间
  13. L1 和 L2的区别
  14. 汉罗塔汉洛塔c++,看不懂ni打我
  15. 一刀工具箱- 语音合成工具
  16. java 基础:方法/函数
  17. “阳”后第1 2 3 4 5 6 7天的症状详解
  18. CentOS 安装HTTP代理服务器Tinyproxy---配置简捷
  19. 海康 大华 华为 宇视等安防摄像头、NVR、平台网关通过GB28181接入LiveGBS流媒体服务实现WEB无插件直播
  20. 基于磁链模型的非线性观测器

热门文章

  1. ChatGPT将代替60%的Android岗位……
  2. 实战:React全家桶仿PC端《快看漫画》(部分)
  3. 作为女程序的我以后再也不想和产品经理说话了!!!
  4. adsp充电框架梳理
  5. 日本电商Rakuten:最凶猛的国际扩张者
  6. Linux系统之软件管理
  7. 周杰伦在快手直播焕发第二春
  8. Java模拟发送Http请求详细示例
  9. 获得自定义的所有相簿
  10. 用模拟开关芯片直接驱动继电器电路