khala能够对设备进行生命周期管理,并提供了与生命周期相关的接口,用户只需在具体的设备类型实现类中重写这些生命周期接口,即可享受khala对于生命周期管理的同时定制与业务相关的操作。具体接口解释如下:

onLoginCheckMsg():

  进行登录检查,在此可以通过查询DB等方式检查登录设备账号是否合法,可以为连接设备设置设备ID(此ID必须唯一,将被视为设备key,若出现重复将执行onLoginFailureMsg,若未设置将以临时ID值作为ID key),若账号检查失败,设置失败回复消息并直接返回false即可。若检查成功,并且设置的ID未重复,将完成登录操作并执行onLoginSuccessMsg。

onLoginSuccessMsg():

  登录成功,在此可以执行登录成功后的相关操作。此时设备进入登录设备的生命周期。

onLoginFailureMsg():

  登录异常,设置ID与已登录的设备ID冲突,一般表明该账号已登录。

onLogoutMsg():

  注销操作,表明该账号退出登录。此操作结束后,将执行releaseConnNode释放该设备的相关资源,并结束该设备的登录生命周期,并最终断开连接。

releaseConnNode():

  释放设备资源。将在退出设备生命周期时被执行,一般在设备执行注销操作后执行,但在设备异常退出的时候,也会执行该操作。

  我们通过建立一个MyUsrType的设备类型为来体验khala的设备生命周期。MyUsrType通过继承于NodeType享受登录设备管理,并对相关的生命周期接口进行重写定制。

我们在mysql中建立名为UsrInfo的表,用来记录设备账号信息。在此我们新建了两个账号,分别为moss1和moss2,且我们通过DB维护了每个账号的不同id。

  我们在onLoginCheckMsg中对登录账号信息查询DB进行检查。具体的DB操作我们可以通过封装mysql++实现,具体相关可百度mysql++文档。若该账号不存在,我们回复登录失败的消息,并返回false,即结束了此次登录请求操作。若该账号存在,我们将DB中保存的ID作为设备ID。并返回true。

virtual bool onLoginCheckMsg(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
//获取账号名
std::string name = msg[KEY_LOGIN_NAME].asString();
//获取密码
std::string passwd = msg[KEY_PASSWD].asString();
//查询DB
UsrInfoResult res = UsrInfoDao::getInstance().queryUsrInfo(name,passwd);
if (!res.isSuccess()) {
//该账号不存在
infoNodePtr->send("login failure,err account!");
return false;
}
//获取DB查询信息
UsrInfoDo usrInfoDo = res.getUsrInfoDo();
//将设备ID设置为DB中保存的ID
infoNodePtr->setId(usrInfoDo.id);
return true;
}

  之后系统将会以该ID做为key对已登录设备进行检查,若该ID在已登录设备中存在,则表明该账号已经登录,将执行onLoginFailureMsg操作。此处我们实现的onLoginFailureMsg操作很简单,仅仅只是告诉客户端该ID所对应的设备账号已经登录,此次登录失败。

virtual bool onLoginFailureMsg(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
infoNodePtr->send("login failure,logined id!");
return true;
}

  若该ID未登录,则会执行相应的登录操作,将该连接信息保存到登录设备池等。并最后执行onLoginSuccessMsg,表明该设备账号登录成功,正式进入登录生命周期中。我们可以在此实现登录成功后的相关操作。我们在此的实现也很简单,告诉客户端此次登录成功,且设备的ID为多少。

virtual bool onLoginSuccessMsg(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
std::stringstream ss;
ss << "login success! your id is:" << infoNodePtr->getId();
infoNodePtr->send(ss.str());
return true;
}

  至于注销操作,依旧只需实现具体的和业务相关的消息返回就行,Khala系统收到注销操作后,将会自行处理之前维护的设备信息,将其释放并调用releaseConnNode释放设备申请的相关资源,最后结束此次登录的生命周期并断开连接。

virtual bool onLogoutMsg(khala::InfoNodePtr& infoNodePtr, Json::Value& msg,
khala::Timestamp time) {
std::stringstream ss;
ss << "logout success! your id is:" << infoNodePtr->getId();
infoNodePtr->send(ss.str());
return true;
}

  因为此次设备并未主动申请相关资源,因此releaseConnNode操作无需进行任何操作,但为了展示releaseConnNode在设备登录生命周期的时机,我们通过系统日志进行相关输出。

virtual void releaseConnNode(khala::InfoNodePtr& infoNodePtr,
khala::Timestamp time) {
LOG_INFO << "this is node id:" << infoNodePtr->getId()<< " release function!";
}

  最后,我们还要为我们的MyUsrType设置类型名,同时在main中进行注册操作,此处不谈。

MyUsrType的完整代码见最后。

  我们通过客户端进行测试(./example/testClient/HelloKhalaClient3.py)。

  我们选择登录操作,并且选择登录类型为usrType,然后输入moss1的账号密码,此时显示我们登录成功,且id为1,正是DB中moss1对应的ID。我们再查询isLogin命令,显示我们已经登录。查询devType,正是我们新创建的MyUsrType类型。

  如果我们输入一个错误的账号密码,结果返回错误的账号,且查询isLogin显示未登录。

  此时我们的moss1账号已经登录,如果我们再开启一个客户端,通过moss1账号进行登录操作。此时返回onLoginFailureMsg中的处理,即该账号已经在别处登录,此次登录失败。

  我们再在已经登录的moss1账号上进行注销操作。我们收到正确的注销操作返回,连接被断开。

  此时我们查询khala服务端日志,显示releaseConnNode被成功执行。

  我们再次开启客户端,并用moss1账号登录,再通过ctr+c强制客户端退出,此时我们再检查日志,显示系统检测到客户端异常退出,同时releaseConnNode依旧得到了执行。因此如果我们在登录连接中申请了相关资源,不管客户端最后是正确被注销退出还是异常情况下退出,只要我们在releaseConnNode中执行了正确的申请资源释放操作,都不会导致服务端因为资源泄露而出错。

  完整的MyUsrType类代码:

#include <khala/NodeType.h>
#include <sstream>
#include"DAO/UsrInfoDao.h"
class MyUsrType: public khala::NodeType {
public:
MyUsrType();
virtual ~MyUsrType();
virtual bool onLoginCheckMsg(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
std::string name = msg[KEY_LOGIN_NAME].asString();
std::string passwd = msg[KEY_PASSWD].asString();
UsrInfoResult res = UsrInfoDao::getInstance().queryUsrInfo(name,
passwd);
if (!res.isSuccess()) {
infoNodePtr->send("login failure,err account!");
return false;
}
UsrInfoDo usrInfoDo = res.getUsrInfoDo();
infoNodePtr->setId(usrInfoDo.id);
return true;
}
virtual bool onLoginSuccessMsg(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
std::stringstream ss;
ss << "login success! your id is:" << infoNodePtr->getId();
infoNodePtr->send(ss.str());
return true;
}
virtual bool onLoginFailureMsg(khala::InfoNodePtr& infoNodePtr,
Json::Value& msg, khala::Timestamp time) {
infoNodePtr->send("login failure,logined id!");
return true;
}
virtual bool onLogoutMsg(khala::InfoNodePtr& infoNodePtr, Json::Value& msg,
khala::Timestamp time) {
std::stringstream ss;
ss << "logout success! your id is:" << infoNodePtr->getId();
infoNodePtr->send(ss.str());
return true;
}
virtual void releaseConnNode(khala::InfoNodePtr& infoNodePtr,
khala::Timestamp time) {
LOG_INFO << "this is node id:" << infoNodePtr->getId()
<< " release function!";
}
virtual const std::string& getObjectTypeName() {
static std::string typeStr(MY_USR_TYPE);
return typeStr;
}
};

6、Khala的登录生命周期管理的更多相关文章

  1. Salesforce 应用生命周期管理

    应用程序生命周期管理 一个Salesforce系统可以有多个版本,最常见的有: production版本:终端用户实际使用的版本 sandbox版本:沙盒环境,用于开发.测试等 在对Salesforc ...

  2. 4-K8S 部署Java应用及应用程序生命周期管理

    1.在kubernetes中部署应用程序流程 准备项目源码-->编译构建-->产出war包,打包到镜像中-->推送到镜像仓库 获取源代码是开发人员提交代码的代码托管地址,有Git.S ...

  3. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  4. 【转】Tomcat组件生命周期管理

    Tomcat组件生命周期管理 Tomcat中Server,Service,Connector,Engine,Host,Context,它们都实现了org.apache.catalina.Lifecyc ...

  5. Castle IOC容器组件生命周期管理

    主要内容 1.生命处理方式 2.自定义生命处理方式 3.生命周期处理 一.生命处理方式 我们通常创建一个组件的实例使用new关键字,这样每次创建出来的都是一个新的实例,如果想要组件只有一个实例,我们会 ...

  6. Java实现生命周期管理机制

    先扯再说 最近一直在研究某个国产开源的MySQL数据库中间件,拉下其最新版的代码到eclipse后,启动起来,然后做各种测试和代码追踪:用完想要关闭它时,拉出它的STOP类想要运行时,发现这个类里赫然 ...

  7. 依赖注入及AOP简述(十一)——生命周期管理 .

    2.     生命周期管理 各种依赖注入框架提供了替开发者管理各种Scope的便利功能,随之而来的就必然是被管理的依赖对象的生命周期管理的问题.所谓生命周期管理,就是一个对象在它所属的Scope中从被 ...

  8. Windows 8 动手实验系列教程 实验5:进程生命周期管理

    动手实验 实验5:进程生命周期管理 2012年9月 简介 进程生命周期管理对构建Windows应用商店应用的开发者来说是需要理解的最重要的概念之一.不同于传统的Windows应用(它们即使在后台仍然继 ...

  9. 快速构建Windows 8风格应用30-应用生命周期管理

    原文:快速构建Windows 8风格应用30-应用生命周期管理 引言 Windows 8 中可以启动多个应用并在其中切换,我们没有必要担心降低系统速度或消耗电池电量. 因为系统会自动挂起(有时会终止) ...

随机推荐

  1. Servlet编码和解码

    1.request.setCharacterencoding("XXX"); 前提是POST提交 在客户端编码对value的值进行编码之前,通知客户端用什么码表(XXX)编码 2. ...

  2. hdu 2438

    Problem Description Mr. West bought a new car! So he is travelling around the city. One day he comes ...

  3. Floyd最小环

    本文转自这里 最小环:从一个点出发,经过一条简单路径回到起点成为环.图的最小环就是所有环中长度最小的. 怎样求最小环呢? 1传统的解决方法(dijkstra):        任意一个最小环环的权值, ...

  4. No2_5.类的高级特性_Java学习笔记_抽象类和成员内部类

    一.抽象类1.所谓抽象类,只声明方法的存在而不去实现它的类:2.抽象类不能被实例化,即不能实现其对象:3.abstract class 类名{ 类体 }4.包含一个或多个抽象方法的类必须声明成抽象类: ...

  5. 关于Repeater中绑定的控件不触发ItemCommand事件

    今天遇到 在repeater 中使用一个button,点击button然后跳转另外一个页面. html. <asp:Repeater ID="repeater" runat= ...

  6. [Mugeda HTML5技术教程之19]制作可定制贺卡

    本文档通过一个实例介绍可定制贺卡的动画的制作过程.实例包含两部分: 1. 动画部分:介绍动画制作过程中如何给祝福词和落款的文本对象命名,如何给定制按钮定义表单动作. 2. 代码部分:介绍贺卡的脚本逻辑 ...

  7. C语言之利用递归将十进制转换为二进制

    #include<stdio.h>#include<stdlib.h>void change2(int num){  if (num != 0)   {   change2(n ...

  8. mongoexport导出数据

    mongoexport用法: /***** Export MongoDB data to CSV, TSV or JSON files.options:  --help                 ...

  9. Spring Data JPA之Hello World

    Spring Data Jpa 配置 使用 Spring Data JPA 进行持久层开发需要的四个步骤: 1.配置 Spring 整合 JPA 2.在 Spring 配置文件中配置 Spring D ...

  10. 学习ReactNative笔记整理一___JavaScript基础

    学习ReactNative笔记整理一___JavaScript基础 ★★★笔记时间- 2017-1-9 ★★★ 前言: 现在跨平台是一个趋势,这样可以减少开发和维护的成本.第一次看是看的ReactNa ...