创建一个简单的 MDM 服务器(2)

四、实现 server URL

接下来以推送最简单的锁屏命令为例,演示如何实现从服务器推送完整的 MDM 消息给注册设备。

首先实现一个简单的Jsp 页面。页面中是一个 html 表单,在<select>标签中我们会列出所有注册设备的 UUID(当然列出设备名称会更好),当你选择一个UUID,点击submit 按钮,服务器会向这个设备推送锁屏命令。

servlet lock 来负责处理这个表单:

Stringudid=request.getParameter("select1");

TokenUpdatetu=TokenUpdate.load(udid);

StringpemPath=request.getSession().getServletContext().getRealPath("/")+"/mdm_push.p12";

// Utils.sendMdmPush(pemPath,tu);

Utils.pushLock(pemPath,tu);

它首先会通过 UUID 查找 TokenUpdate表以获取设备的token、pushMagic 和 unlock token。然后调用 Utils.pushLock方法发送锁屏命令。

pushLock 方法与正常的 APNS 发送么有什么不同,也是借用了 JavaAPNS 框架进行的:

public static int pushLock(String p12Path,TokenUpdate tu) {

       int pushState = 0 ;

       try {

            ApnsService service =

                   APNS.newService()

                           .withCert(p12Path,MDMPASS)

                           .withProductionDestination()

                           .build();

           String mdmPayload = APNS.newPayload().customField("mdm",tu.PushMagic).build();

           System.out.println(mdmPayload);

           String deviceToken=tu.Token;

           deviceToken=parseToken(deviceToken);

           System.out.println("device token="+deviceToken);

           service.push(deviceToken, mdmPayload);

            pushState = 1;

            System.out.println("推送锁屏信息已发送!");

           Command cmd=new Command();

            cmd.command="DeviceLock";

           cmd.deviceid=tu.UDID;

           cmd.status=0;

            cmd.enqueue();

       } catch (Exception e) {

            System.out.println("出错了:"+e.getMessage());

           pushState = 0;

       }

       return pushState;

    }

值得注意的是,它没有使用 PayloadBuilder 来构建默认的消息 payload,而是直接 new 了一个 payload,然后在其中添加了自定义字段"mdm",值为push magic 。

java apns 在推送时需要知道设备的 device token,这个 device token 稍有点奇怪,它不是二进制形式(即 byte 数组),而必须是这些二进制转换成16进制后的字符串形式(string)。parseToken方法就是用来干这个的。它先将数据库中的 token(Base64 encode 后的字符串)反编码(Base64 decode),得到原始 token 的byte 数组,然后逐字节转换为16进制的字符串形式。

服务器并不能立即收到设备的响应,因为这个 APNS 消息是发给苹果推送服务器的。所以在这个方法中,将这条命令同时记录在 commandqueue 表中,方便等下(终端设备)来查找已经发过的指令。commandqueue表结构类似如下:

CREATE TABLE `commandqueue` (

  `id` int(11) NOT NULLAUTO_INCREMENT,

  `command` varchar(45) DEFAULTNULL,

  `deviceid` varchar(45)DEFAULT NULL,

  `status` int(11) DEFAULTNULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=latin1;

 

如果推送证书和注册设备所安装的描述文档经过了苹果的校验,接下来的苹果会通知设备来访问 MDM 服务器,即我们在配置描述文档时指定的那个服务器 URL:

因此接下来要实现servlet server。server类主要处理两类消息:Status:Idle消息和 Acknowledge 消息:

protected void doPut(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

StringplistStr=Utils.is2string(request.getInputStream());

System.out.println("*********ReceivedMessage:***********\n"+plistStr);

try{

Map<String,Object>plist=Plist.fromXml(plistStr);

PrintWriter out = response.getWriter();

if(plist!=null){

StringmsgType=MessageType.typeOfMessage(plist);

if(msgType.equals("Status:Idle")){

Stringdeviceid=plist.get("UDID").toString();

 Command cmd = Command.dequeue(deviceid);

 if(cmd.command!=null &&"DeviceLock".equals(cmd.command)){

 String commandString =CommandPlist.deviceLock(cmd);

 Command.updateStatus(cmd.id, 1);

 System.out.println("——————-Commandwill send.—————");

 response.setHeader("content-type","application/xml;charset=UTF-8");

 response.setCharacterEncoding("UTF-8");

 String filename = "DeviceLock.plist";

 response.setHeader("Content-Disposition","attachment; filename=" + filename);

 

 

 System.out.printf("%s\n",commandString);

 out.write(commandString);

 out.flush();

 out.close();

 }

 

}elseif(msgType.equals("Acknowledged")){

String cmdID = (String)plist.get("CommandUUID");

Integer integer=Integer.parseInt(cmdID);

Command.updateStatus(integer, 2);

System.out.println("%s\n——————-Commandexecution completed.—————\n");

out.println();

out.close();

}

}

}catch(Exceptione){

e.printStackTrace();

}

}

当苹果的 APNS 服务器通知设备访问 MDM 服务器时,设备首先会发送一个 Status:Idle 消息(如果设备空闲),表示 MDM 服务器现在可以把指令取给它执行。

在 server.java 里,首先处理的就是这个消息。它首先从 commandqueue 表中取出一个“曾经”发送给这个设备的有效命令(我们通过status 字段识别,2 是已经执行完的命令,1 是还在执行的命令,0 是已经推送但未执行的命令),然后组装成 Plist 文件响应给它。

在组装 Plist 文件时,在 commandUUID 中填入该命令在 commandqueue 表中的主键(id 字段),这样当设备执行完命令,我们可以依据id 值回写执行状态。

设备执行完命令,会再次向 server 发送 Acknowledged 消息。对于这个消息,server.java 需要根据 commandUUID 回写命令执行状态,然后简单回复一个空响应(即http 200),并关闭 http 连接。


  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SAP MDM(Master Data Management)是一种集中管理企业主数据的解决方案。在SAP中,可以使用两个不同的客户端来传输数据,即源客户端和目标客户端。 源客户端是指存储和提供主数据的客户端。它可以是一个单独的SAP系统,也可以是一个非SAP系统。在源客户端上,我们可以创建、编辑、维护和管理主数据。当需要将主数据传输到目标客户端时,可以使用不同的方法和工具,如数据迁移工具(如LSMW、SAP Data Services)或手动导出和导入主数据。 目标客户端是指需要接收并使用主数据的客户端。它可以是一个SAP系统,也可以是另一个关联的非SAP系统。目标客户端使用传输的主数据来支持业务流程和决策制定。一旦主数据被传输到目标客户端,可以根据业务需要进行进一步的编辑和管理。 在将数据从源客户端传输到目标客户端时,需要确保数据的完整性和准确性。这意味着需要进行数据验证和清洗,以避免传输错误或不准确的数据。同时,还需要确定传输的频率和时间,以确保目标客户端中的数据始终是最新的。 总而言之,SAP MDM允许在两个客户端之间传输主数据。源客户端负责管理和维护主数据,而目标客户端用于接收和使用主数据。数据的传输可以通过各种方法和工具来完成,并需要确保数据的准确性和完整性。这帮助企业更好地管理和利用它们的主数据,支持业务流程和决策制定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值