C#开发BIMFACE系列36 服务端API之:回调机制
在《C# 开发 BIMFACE 系列文章》中介绍了模型转换、模型对比接口。这2个功能接口比较特殊,发起请求后,逻辑处理是在BIMFACE云端进行的,通常需要5~10分钟。当逻辑处理完成后,BIMFACE通过回调机制通知对比结果。
BIMFACE支持回调机制。在调用方发起模型转换、模型集成、模型对比、生成离线数据包等操作时,可以通过传入参数callback的方式来启用回调机制。 在BIMFACE处理完相应操作后,根据调用方传入的回调地址通知调用方相应操作的结果。

URL参数:

signature(签名):为了确保回调消息是由BIMFACE发出的,调用方在收到回调消息后,须验证签名。签名的计算方式:MD5(``appKey:appSecret:compareId:status:nonce''),如果调用方计算的签名与BIMFACE返回的签名一致,则证明该消息是安全可靠的。
应用收到回调后,须向BIMFace发送回执,回执消息:HTTP STATUS 200
Callbak示例:
* 调用方对文件1685236328506848发起了模型转换,并且传入的回调地址是:https://my.app.com/callback。 * BIMFACE在模型转换任务处理完成后,会发送一个get请求到调用方的callback地址:
https://my.app.com/callback?fileId=1685236328506848&status=success&thumbnail=38044a282f55cb26e3704643dccd2b55/thumbnail/96.png,38044a282f55cb26e3704643dccd2b55/thumbnail/256.png&reason=&signature=99a6fccb1894dfdb4cce48fd5ec58110&nonce=123abc * 调用方接收到这条请求后,可以进行signature的验证,并发送回执消息。
特别说明
BIMFACE的回调机制与微信公众号或者小程序开发类似,需要开发者提供开发者服务器,且有正式合法域名或者外网IP,对外公布一个地址,BIMFACE服务器能访问到该地址才可以。
如果无法提供有效的回调地址,则只能通过手动调用 模型转换、模型集成、模型对比、生成离线数据包等操作的其他API来获取对应的处理结果。
在.NET平台下实现该功能可以使用 WebService、一般处理程序、WebAPI等技术方式实现。下面介绍在一般处理程序中实现的思路与步骤。
1、配置BIMACE开发者账号信息。
在web.config 或者 app.config 文件中配置开发者账号信息,供验证消息签名时使用。

2、获取BIMFace服务器发送的回调请求参数。
long fileId = context.Request.QueryString["fileId"].ToLong(); // 文件ID
string status = context.Request.QueryString["status"]; // 转换的结果
string reason = context.Request.QueryString["reason"]; // 若转换失败,则返回失败原因
string thumbnail = context.Request.QueryString["thumbnail"]; // 缩略图地址
string nonce = context.Request.QueryString["nonce"]; // 回调随机数
string signature = context.Request.QueryString["signature"]; // BIMFACE的加密签名
3、根据请求参数计算签名。
签名的计算方式:MD5(``appKey:appSecret:compareId:status:nonce'')
/// <summary>
/// 根据回调的参数计算签名
/// </summary>
/// <param name="appKey">开发者秘钥</param>
/// <param name="appSecret">开发者密码</param>
/// <param name="fileId">BIMFace发出的回调信息:文件ID</param>
/// <param name="status">BIMFace发出的回调信息:转换的结果</param>
/// <param name="nonce">BIMFace发出的回调信息:回调随机数</param>
/// <returns></returns>
public static string GetCallbackSignature(string appKey, string appSecret, long fileId, string status, string nonce)
{
return string.Format("{0}:{1}:{2}:{3}:{4}", appKey, appSecret, fileId, status, nonce).EncryptByMD5();
}
其中使用到的扩展方法 EncryptByMD5() 实现如下:
/// <summary>
/// 自定义扩展方法:使用 MD5(不可逆加密) 算法加密字符串。返回二进制形式的字符串。字符串的编码方式为UTF8。
/// </summary>
/// <param name="this">扩展对象。字符串。编码方式为UTF8</param>
/// <param name="caseType">字符串大小写。默认小写</param>
/// <returns></returns>
public static string EncryptByMD5(this string @this, CaseType caseType = CaseType.Lower)
{
using (MD5 md5 = MD5.Create())
{
var sb = new StringBuilder();
byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(@this));
foreach (byte bytes in hashBytes)
{
sb.Append(bytes.ToString("X2"));//X2 表示二进制
} return caseType == CaseType.Upper ? sb.ToString() : sb.ToString().ToLower();
}
}
4、验证签名。
将步骤3中的计算结果与BIMFace发出的回调消息签名做对比,如果签名一直则证明该消息是安全可靠的。
/// <summary>
/// 验证BIMFace发出的回调消息签名信息是否安全可靠
/// </summary>
/// <param name="appKey">开发者秘钥</param>
/// <param name="appSecret">开发者密码</param>
/// <param name="fileId">BIMFace发出的回调信息:文件ID</param>
/// <param name="status">BIMFace发出的回调信息:转换的结果</param>
/// <param name="nonce">BIMFace发出的回调信息:回调随机数</param>
/// <param name="signature">BIMFace发出的回调信息:签名</param>
/// <param name="custCalcSignature">输出参数:根据BIMFACE平台的加密规则计算出来的签名信息</param>
/// <returns></returns>
public static bool CheckCallbackSignature(string appKey, string appSecret, long fileId, string status, string nonce, string signature, out string custCalcSignature)
{
/* signature(签名):为了确保回调消息是由BIMFace发出的,应用在收到回调消息后,须验证签名。
* 签名的计算方式:MD5("appKey:appSecret:fileId:status:nonce"),如果应用计算的签名与BIMFace返回的签名一致,则证明该消息是安全可靠的。
*/
custCalcSignature = GetCallbackSignature(appKey, appSecret, fileId, status, nonce); return custCalcSignature == signature;
}
5、根据签名验证结果做出回执响应消息。
如果验证签名成功则可以将模型转换、模型集成、模型对比、生成离线数据包等操作的处理结果写入数据库保存供后续其他业务逻辑使用。
签名成功后,须向BIMFace发送回执,回执消息:HTTP STATUS 200。
bool checkSignature = CallbackUtils.CheckCallbackSignature(appKey, appSecret, fileId, status, nonce, signature, out custCalcSignature);
if (checkSignature)
{
tip = "[BIMFace发出的回调信息签名验证成功!]"
+ Environment.NewLine
+ callbackResponse;
LogUtility.Info(tip); //Todo 此处可以根据fileId把相关的信息写入数据库中 // 回执消息:应用收到回调后,须向BIMFace发送回执,回执消息:HTTP STATUS 200
context.Response.Write("HTTP STATUS 200");
}
else
{
tip = "[BIMFace发出的回调信息签名验证不通过!]"
+ Environment.NewLine
+ callbackResponse
+ Environment.NewLine
+ "自定义计算签名 custCalcSignature:" + custCalcSignature; LogUtility.Error(tip); context.Response.Write(tip);
}
如果签名验证失败,则需要将签名信息写入文本日志供分析原因使用。此时通过编码方式实现邮件、短信、微信消息等方式通知开发者回调程序处理结果不正确,使其及时知道业务系统的运行状况。
6、发布程序并使用该回调地址。
程序完成后发布到开发者服务器。在模型转换、模型集成、模型对比、生成离线数据包等操作的API接口参数中使用该回调地址。
完整的代码如下:
/// <summary>
/// BimFace回调处理
/// </summary>
public class BimFaceHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.ContentEncoding = Encoding.UTF8; string appKey = ConfigUtility.GetAppSettingValue("BIMFACE_AppKey");
string appSecret = ConfigUtility.GetAppSettingValue("BIMFACE_AppSecret");
string uid = context.Request.QueryString["uid"]; // SparkBimFace #region 校验
if (appKey.IsNullOrWhiteSpace())
{
LogUtility.Error("BIMFace appKey 配置项没有配置!"); return;
} if (appSecret.IsNullOrWhiteSpace())
{
LogUtility.Error("BIMFace appSecret 配置项没有配置!"); return;
} if (uid.IsNullOrWhiteSpace())
{
LogUtility.Error("[非法请求]回调地址Url链接中的参数 uid 没有配置或者配置的值为空!"); return;
}
#endregion long fileId = context.Request.QueryString["fileId"].ToLong(); // 文件ID
string status = context.Request.QueryString["status"]; // 转换的结果
string reason = context.Request.QueryString["reason"]; // 若转换失败,则返回失败原因
string thumbnail = context.Request.QueryString["thumbnail"]; // 缩略图地址
string nonce = context.Request.QueryString["nonce"]; // 回调随机数
string signature = context.Request.QueryString["signature"]; // BIMFACE的加密签名 string callbackResponse = string.Format("fileId:{0},\r\nstatus:{1},\r\nreason:{2},\r\nthumbnail:{3},\r\nnonce:{4},\r\nsignature:{5}",
fileId, status, reason, thumbnail, nonce, signature);
string tip;
string custCalcSignature; bool checkSignature = CallbackUtils.CheckCallbackSignature(appKey, appSecret, fileId, status, nonce, signature, out custCalcSignature);
if (checkSignature)
{
tip = "[BIMFace发出的回调信息签名验证成功!]"
+ Environment.NewLine
+ callbackResponse;
LogUtility.Info(tip); //Todo 此处可以根据fileId把相关的信息写入数据库中 // 回执消息:应用收到回调后,须向BIMFace发送回执,回执消息:HTTP STATUS 200
context.Response.Write("HTTP STATUS 200");
}
else
{
tip = "[BIMFace发出的回调信息签名验证不通过!]"
+ Environment.NewLine
+ callbackResponse
+ Environment.NewLine
+ "自定义计算签名 custCalcSignature:" + custCalcSignature; LogUtility.Error(tip); context.Response.Write(tip);
} context.Response.End();
} /// <summary>
/// 该属性获得一个布尔值,指示另一个请求是否可以使用该HTTP处理程序的实例。
/// <para>如果设置为true,能提高性能,但要注意线程之间安全性问题。如果设置为false,则线程是安全的</para>
/// </summary>
public bool IsReusable
{
get
{
return false;
}
}
}
C#开发BIMFACE系列36 服务端API之:回调机制的更多相关文章
- C#开发BIMFACE系列40 服务端API之模型集成
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 随着建筑信息化模型技术的发展,越来越多的人选择在云端浏览建筑模型.现阶段的云端模型浏览大多是基于文件级别,一次只可以浏览一 ...
- C#开发BIMFACE系列41 服务端API之模型对比
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在建筑施工图审查系统中,设计单位提交设计完成的模型/图纸,审查专家审查模型/图纸.审查过程中如果发现不符合规范的地方,则流 ...
- C#开发BIMFACE系列42 服务端API之图纸对比
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在我的前一篇博客<C#开发BIMFACE系列42 服务端API之图纸对比>中详细介绍了BIMFACE服务端接口 ...
- C#开发BIMFACE系列43 服务端API之图纸拆分
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在上一篇博客<C#开发BIMFACE系列42 服务端API之图纸对比>的最后留了一个问题,在常规业务场景下,一 ...
- C#开发BIMFACE系列44 服务端API之计算图纸对比差异项来源自哪个图框
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在前两篇博客<C#开发BIMFACE系列42 服务端API之图纸对比>.<C#开发BIMFACE系列43 ...
- C#开发BIMFACE系列46 服务端API之离线数据包下载及结构详解
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在前一篇博客<C#开发BIMFACE系列45 服务端API之创建离线数据包>中通过调用接口成功的创建一个离线数 ...
- C#开发BIMFACE系列6 服务端API之获取文件信息
在<C#开发BIMFACE系列4 服务端API之源上传文件>.<C#开发BIMFACE系列5 服务端API之文件直传>两篇文章中详细介绍了如何将本地文件上传到BIMFACE服务 ...
- C#开发BIMFACE系列4 服务端API之源上传文件
在注册成为BIMFACE的应用开发者后,要能在浏览器里浏览你的模型或者获取你模型内的BIM数据, 首先需要把你的模型文件上传到BIMFACE.根据不同场景,BIMFACE提供了丰富的文件相关的接口. ...
- C#开发BIMFACE系列3 服务端API之获取应用访问凭证AccessToken
系列目录 [已更新最新开发文章,点击查看详细] BIMFACE 平台为开发者提供了大量的服务器端 API 与 JavaScript API,用于二次开发 BIM 的相关应用. BIMFACE ...
随机推荐
- [徐州网络赛]Longest subsequence
[徐州网络赛]Longest subsequence 可以分成两个部分,前面相同,然后下一个字符比对应位置上的大. 枚举这个位置 用序列自动机进行s字符串的下标转移 注意最后一个字符 #include ...
- voxelmorph配置
简介 VoxelMorph使用CNN实现了非监督的医学图像配准,速度较之前的方法有很大提升.主要特点有: 提出了一种基于学习的解决方案,不需要在训练过程中获取诸如ground truth对应或解剖标志 ...
- 能够伪装为 win 10 的 kali 体验与中文设置
前言 作为习惯性捣鼓各类操作系统,时长也会使用 Kali 系统,之前看到有新的版本发行 传闻这个版本和之前的版本在系统界面和壁纸上都做了更新,还能一键设置 win 10 的系统界面 对此决定下载体验一 ...
- 37)PHP,获取数据库值并在html中显示(晋级2)
下面的是上一个的改进版,我知道为啥我的那个有问题了,因为我的__construct()这个函数的里面的那个变量名字搞错了,哎,这是经常犯得毛病,傻了吧唧,气死我了. 之前的那个变量的代码样子: cla ...
- Yahoo!团队:网站性能优化的35条黄金守则
Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客并在各种会议上参与探讨.最佳实践的核心 ...
- 西甲官方APP承认监听球迷,或给国内应用带来新思路
在此前,一般巨头或者官方推出的产品.应用等总是值得信赖的.出问题的话一般都是"不可抗拒的外力因素",比如被黑客攻破导致用户隐私被窃取等.但自从Facebook的用户隐私泄露丑闻被曝 ...
- Spatial crowdsourcing
空间众包(Spatial crowdsourcing)分类 空间众包是将一组空间任务众包给一组工作人员的过程,这要求工作人员实际位于该位置以执行相应的任务. 空间众包可以根据员工的动机分为两类:基于奖 ...
- 吴裕雄--天生自然python学习笔记:pandas模块强大的数据处理套件
用 Python 进行数据分析处理,其中最炫酷的就属 Pa ndas 套件了 . 比如,如果我 们通过 Requests 及 Beautifulsoup 来抓取网页中的表格数据 , 需要进行较复 杂的 ...
- 吴裕雄--天生自然python学习笔记:爬取我国 1990 年到 2017年 GDP 数据并绘图显示
绘制图形所需的数据源通常是不固定的,比如,有时我们会需要从网页抓取, 也可能需从文件或数据库中获取. 利用抓取网页数据技术,把我国 1990 年到 2016 年的 GDP 数据抓取出来 ,再利用 Ma ...
- 个人云主机 博客上线 家用宽带-树莓派2-certbot-docker 运行环境简介
https://blog.cuidp.top/ 博客主页,目前刚建好,没什么数据 服务是 https://github.com/TryGhost/Ghost 现插件是https://github.co ...