授权激活

授权激活指的是从服务器获取license文件后保存在本地,供其它程序使用。激活后的license文件默认位置如下:

  • Linux:“{当前用户}/BitAnswer”
  • Windows:“{系统盘}/ProgramData/BitAnswer”

该目录也可以通过Bit_SetRootPath来自定义。


授权激活支持在线和离线两种方式。

在线激活

  • 使用SN激活

调用Bit_UpdateOnline,传入SN激活。

示例:

// 激活SN(YUFTB2AY4AAACVB6)
BIT_STATUS status = Bit_UpdateOnline(NULL, “YUFTB2AY4AAACVB6”, application_data);
If (status == BIT_SUCCESS) {
    // 激活成功
    printf(“激活成功\n”);
} else {
    // 激活失败,错误码是status
    printf(“激活失败,错误码%d\n”,status);
}
  • 使用BIT-ID激活

当SN与BIT-ID已经在服务端绑定过,则可以在客户端使用BIT-ID直接激活。

使用Bit_UpdateOnline激活,第二个参数传入#0,#1,#....,代表激活第一个BIT-ID,激活第二个BIT-ID,激活第N个BIT-ID。

示例:

// 激活插入的第一个BIT-ID
BIT_STATUS status = Bit_UpdateOnline(NULL, “#0”, application_data);
If (status == BIT_SUCCESS) {
    // 激活成功
    printf(“激活成功\n”);
} else {
    // 激活失败,错误码是status
    printf(“激活失败,错误码%d\n”,status);
}

// 激活插入的第二个BIT-ID
Bit_UpdateOnline(NULL, “#1”, application_data);

离线激活

  • 标准流程

    • 在需要激活的设备上调用Bit_GetRequestInfo接口获取请求串。

    • 将请求串拷贝到可以联网的设备,上传到比特授权云平台来获取license串。

    • 将license串拷贝到需要激活的设备上调用Bit_ApplyUpdateInfo接口进行激活。

离线激活流程

示例:

BIT_STATUS status = BIT_SUCCESS;
BIT_CHAR buff[1024] = { 0 };
BIT_UINT32 lenBuff = sizeof(buff);

// 获取请求串
status = Bit_GetRequestInfo(“<SN>”, application_data,  BINDING_LOCAL, buff, &lenBuff);
if (status == BIT_SUCCESS) {
    // 请求串获取成功,保存在buff,长度时lenBuff
} else {
    // 获取请求串错误
}

// 拷贝到可以联网的设备,获取license串,最后拷贝会待激活设备
BIT_CHAR *pLicense = “<拷贝的license串>”;
status = Bit_ApplyUpdateInfo(application_data, pLicense, buff, &lenBuff);
if (status == BIT_SUCCESS) {
    // 激活成功
} else {
    // 激活失败
}
  • 使用设备码激活

对于标准的激活流程需要在产生请求串时输入SN,请求串产生后还需要将其拷贝出来。但是在某些涉密单位不允许向外拷贝文件,而请求串又太长,手动输入太麻烦,因此比特授权云平台支持使用设备码进行激活。

设备码的激活流程和标准的离线激活流程一样,只是在获取请求串时,获取的是易手输的设备码。

示例:

BIT_STATUS status = BIT_SUCCESS;
BIT_CHAR buff[1024] = { 0 };
BIT_UINT32 lenBuff = sizeof(buff);

// 获取请求串
status = Bit_GetRequestInfo(NULL, application_data,  REQ_TYPE_MID, buff, &lenBuff);
if (status == BIT_SUCCESS) {
    // 设备码获取成功,保存在buff,长度时lenBuff
} else {
    // 获取设备码错误
}
// 获取的设备类似:BRW118347F668638A02D5D069F64DA0199D200A531AD13C80C2
  • 使用单项升级串

当设备已经激活,后续如果需要对授权进行升级,就可以不需要产生请求串,而直接通过比特授权云平台下发license串。

使用license串时调用Bit_ApplyUpdateInfo

  • 比较
标准离线激活 设备码激活
是否需要输入SN?
请求串的长度 300个字节以上 100字符以内(容易手动输入、拷贝)
是否支持终端标识?(自定义指纹) 支持
支持增量更新?(只升级更新的部分) 支持

内存授权

内存授权不需要激活就可以直接使用。

  • 获取license串

使用离线的方式获取到license串,获取到的串如下图:

<bitLicense>
    <version>3</version>
    <sn>FPIW6BX5********</sn>
    <code>Uk4GSI3jwrh…………………nLc=</code>
</bitLicense>
  • 读取license串里的code部分,组合成“lic:// Uk4GSI3jwrh……”

  • 调用Bit_Login时传入

BIT_HANDLE handle = NULL;
BIT_STATUS status = Bit_Login(
                “lic:// Uk4GSI3jwrh……”,
                NULL,
                application_data,
                &handle,
                BIT_MODE_LOCAL);
If (status == BIT_SUCCESS) {
    // 内存license加载成功
}

授权检查

开发商需要在软件里设置授权检查点,一般来讲在软件开始运行时调用Bit_Login来检查是否有可用的授权,在运行到某个功能点时调用Bit_QueryFeature来检查授权里是否包某个特征项。

  • 检查license

使用Bit_Login来检查license是否有效。

示例:

BIT_STATUS status = BIT_SUCCESS;
BIT_HANDLE handle = NULL;

status = Bit_Login(NULL, NULL, application_data, &handle, BIT_MODE_AUTO);
if (status == BIT_SUCCESS) {
    // 获取license成功
    // 执行业务逻辑
} else {
    // 获取license失败
}
  • 检查特征项

使用Bit_QueryFeature来检查特征项是否有效。

示例:

BIT_STATUS status = BIT_SUCCESS;
BIT_HANDLE handle = NULL;
BIT_UINT32 capacity = 0;

status = Bit_Login(NULL, NULL, application_data, &handle, BIT_MODE_AUTO);
if (status != BIT_SUCCESS) {
    // 获取license失败
    return;
} 
status = Bit_QueryFeature(handle, <特征项Id>,  &capacity);
if (status == BIT_SUCCESS) {
    // 特征项有效
    // 执行业务逻辑
} else {
    // 获取特征项失败
}
  • 程序运行过程中的检查

当程序运行过程中授权到期时,开发商软件可以通过如下方式检测到:

集团授权:设置心跳回调函数,在回调函数里处理到期事件(参考心跳认证)。

单机授权:定期调用Bit_GetSessionInfo来检查授权是否到期。

授权配置

客户端支持通过配置文件或者环境变量来控制授权行为,例如:配置客户端的授权服务器地址;配置授权模式等。

配置文件

配置文件目前仅支持配置授权服务地址。

配置文件存在两个地方,一个是授权目录,一个是软件当前目录,如果都存在则优先级是:授权目录 > 软件当前目录。

授权目录,默认地址:

  • Linux:“{当前用户}/BitAnswer/{product-code}/bit_config.xml”
  • Windows:“{系统盘}/ProgramData/BitAnswer/{product-code}/bit_config.xml”

其中product-code是产品路径。

内容:

<?xml version="1.0" encoding="UTF-8"?>
<BitConfig>
    <Server Host="<集团服务IP>" Type="bit" Port="<集团服务端口>" Timeout="8" />
</BitConfig>

环境变量

名称 说明
BITANSWER_LICENSE 格式1:bit://ip1:port,bit://ip2:port
格式2:port@ip1,port@ip2, port@ip3
格式3:port@ip1:port@ip2,:port@ip3
指定license的地址,目前最多支持设置6个ip地址
BITANSWER_CONNECT_TIMEOUT 数字(最小1秒,最大32秒,默认3秒) 设置网络超时时间,单位秒
BITANSWER_CONNECT_RETRY_COUNT 数字(最小0次,最大10次,默认3次) 设置网络重试次数
BITANSWER_MODE wait | nowait 设置Query的模式。
wait:排队等待。
nowait:立即返回
BITANSWER_WAIT_TIMEOUT 数字(最小16s,最大1296000s(15天),默认0,代表永久等待) 设置wait模式的等待时间

自定义环境变量前缀,使用Bit_SetCustomInfo可以自定义前缀。

示例:

CHAR *pPre = “BIT”;
Bit_SetCustomInfo(CUSTOM_VENDOR_CODE, pPre, strlen(pPre));

// 设置成功之后,就可以使用类似“BIT_MODE, BIT_LICENSE, BIT_CONNECT_TIMEOUT…”这样的名称设置环境变量

如果环境变量和配置文件同时存在,则优先级是:环境变量 > 配置文件。

集团授权配置客户端IP轮询

对于集团授权,客户端需要配置IP才可以访问,当客户端配置了多个IP时,客户端在检查授权时会挨个匹配,直到找到可用的license。

以下场景,可以考虑使用客户端轮询:

  • 增加网络的可靠性。当某一个服务器的网络出现问题时,不影响客户端的运行。
  • 根据地理位置做负载均衡。例如:开发商在北京激活5个license,在上海激活5个license,对于北京的用户可以配置“北京IP,上海IP”,对于上海的用户可以配置“上海IP,北京IP”。

IP配置

当客户端请求集团授权失效后,就会尝试连接下一个IP,其顺序按照配置文件的顺序从上到下,如果是环境变量,则从前到后。

  • 配置文件顺序示例(匹配顺序ipA-ipB-ipC):
// 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<BitConfig>
    <Server Host="ipA" Type="bit" Port="8273"/>
    <Server Host="ipB" Type="bit" Port="8273" />
    <Server Host="ipC" Type="bit" Port="8273" />
</BitConfig>
  • 环境变量顺序示例(匹配顺序ipA-ipB-ipC):
BITANSWER_URL=port@ipA,port@ipB,port@ipC

服务器选择

客户端选择服务器只会发生在首次连接时,一旦授权成功,后续的操作就只针对当前服务。

一般来讲,用户的调用流程如下:

选择服务器

对于13.4.0及下版本的客户端库,调用Bit_Login时会连接集团服务,只会检查SN是否有效(不检查特征项)。

示例说明:

  1. 有A(包含特征项A),B(包含特征项B),C(包含特征项A,B,C)三台服务器。
  2. 客户端调用Bit_Login连接到服务A。
  3. 客户端调用Bit_QueryFeatureEx2(handle, B, …),请求B特征项,由于handle已经连接到了A,所以在A服务器上查找B,没有找到B,直接报错“特征项不存在”。

对于13.4.0以上版本的客户端库,支持了一种新的登录模式LOGIN_MODE_CREATE_HANDLE_ONLY,在该模式下,Bit_Login只创建本地的handle(不连接集团服务),使用该handle调用Query相关接口才会连接服务,此时,服务会同时检查SN的有效性以及特征项的有效性。

注意:该功能需要服务端升级到13.4.0以上版本才可以支持,对于13.4.0及以下版本的服务调用会报错“服务版本太老”。

示例:

  1. 有A(包含特征项A),B(包含特征项B),C(包含特征项A,B,C)三台服务器。
  2. 客户端调用Bit_Login(LOGIN_MODE_CREATE_HANDLE_ONLY, …),创建本地handle。
  3. 客户端调用Bit_QueryFeatureEx2(handle, B, …),请求B特征项,由于handle还没有指定服务器,所以开始轮询查找包含特征项B的服务器,找到后将handle与服务器的session关联。
  4. 客户端如果继续使用上面的handle,去Query(handle, C, …),此时就只会在B服务器上查找C特征项,如果没有就会报“特征项不存在”的错误。

开发商如何实现不同特征项连接不同的服务器?
每一个特征项用一个不同的handle。

集团授权配置心跳认证

当客户端连接到集团授权,就会启动一个后台线程来维护客户端与集团服务的心跳连接,当超过10分钟(默认值)客户端没有发送过心跳,集团服务就会释放占用的用户数。

客户端的心跳周期是:1/2个timeout时间(默认5分钟),如果本次心跳失败,则下一次的心跳周期是10秒。

心跳模式

  • 自动心跳

Bit_Login到集团授权时,会启动自动心跳。

  • 手动心跳

手动心跳前需要调用Bit_SetAttr关闭自动心跳。

关闭后调用Bit_Heartbeat来触发心跳。

示例:

BIT_STATUS status = BIT_SUCCESS;
BIT_UINT32 enableHb = 0;
status = Bit_SetAttr(NULL, ATTR_HB_AUTO_ENABLE,  &enableHb);
if (status != BIT_SUCCESS) {
    // 禁用自动心跳失败
    return;
}

BIT_UINT32 reconnectsNum = 0;
// handle 来自于Bit_Login
status = Bit_Heartbeat(handle,  &reconnectsNum);
if (status != BIT_SUCCESS) {
    // 心跳失败
    return;
}

心跳回调

客户端连接到集团授权后,当集团授权失效(授权到期,服务器关闭,…),开发商软件需要处理该消息(例如:停止当前作业)。

心跳状态与license状态相关,当心跳重试次数达到上限或者断开时间超过timeout,则认为授权失效,心跳断开,反之心跳就会自动重试。

开发商软件通过向客户端库注册心跳回调函数来捕获心跳状态:

  • 注册心跳失败回调

客户端心跳连接失败时,每重试一次就会触发一次,通过Bit_SetAttr来注册心跳失败回调。

示例:

/*
  handle:心跳失败对应的handle
  status:心跳失败的状态码
  pData:保留
*/
void HbRetryFailedCallback(BIT_HANDLE handle, BIT_STATUS status, void *pData) {
}

Bit_SetAttr(handle, ATTR_HB_RETRY_FAILED_CALLBACK, HbRetryFailedCallback);
  • 注册心跳停止回调

客户端心跳连接断开后,会触发一次,使用Bit_SetAttr注册心跳停止回调。

示例:

/*
  handle:心跳失败对应的handle
pData:保留
*/
void HbStopedCallback(BIT_HANDLE handle, void *pData)  {
}

Bit_SetAttr(handle, ATTR_HB_STOPED_CALLBACK, HbStopedCallback);

心跳配置

参考Bit_SetAttr说明。

Session重建

客户端登录集团服务后会在服务端创建Session,该Session保存了客户端与集团服务的会话信息。

当服务端Session丢失后(服务重启),客户端的心跳会检测到并重建Session,如果Session重建成功则恢复占用的授权点数,如果重建失败,则通过回调函数通知开发商软件。

当客户端Session丢失后(客户端强杀,崩溃),服务端会保持之前占用的点数,超过timeout时间后,集团服务就会自动释放。如果需要立即释放,需要在调用Bit_Login时设置长连接属性。

单机授权智能认证

对于单机授权,如果设置了智能认证选项,客户端每天就会连一次服务器进行认证。

Bit_Login成功后,会创建一个线程用来智能认证,如果认证成功,下一次的认证就是24小时后,如果认证失败,1分钟之后会再次尝试。

对于设置了强制认证属性的授权码,此机制可以保证其便利的用户体验。

授权借出

授权借出指的是从授权服务器借出一定的点数给客户端离线使用。

场景:

当用户无法连接到集团授权时才需要借出使用,例如:公司购买了集团授权供员工使用,但是有的员工需要在家里加班或者出差使用,借出后占用一个授权点数,借出到期后授权点数自动返还(可以调用Bit_CheckIn主动归还)。

调用Bit_CheckOutSn进行在线借出。

注意:只有集团授权和帐号授权勾选了借出属性后才支持借出。

集团授权活跃检测

集团授权的点数对于用户来讲非常的昂贵,用户希望在客户端空闲时能自动释放授权供其他人使用,此时就需要用到此功能。

开发商的软件需要调用Bit_SetSessionState向集团服务报告当前客户端的状态,该状态通过心跳传递给集团服务。

调用示例见Bit_SetSessionState