创建一个简单的 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 连接。

创建一个简单的 MDM 服务器(2),布布扣,bubuko.com

时间: 2024-11-03 03:43:32

创建一个简单的 MDM 服务器(2)的相关文章

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

前提:已获得 APNS 证书 ,已完成 MDM 配置描述文件的制作.请参考< MDM 证书申请流程 >一文和<配置MDM Provisioning Profile>. 环境:OSX 10.9.2,JDK 1.6,Eclipse JavaEE Helois,Tomcat 7.0 一.前言 <THE IOS MDMPROTOCOL>(即Inside Apple MDM)一文中描述了一个简单 MDM Server Python 实现(server.py).笔者也曾参照此文配置

利用node的http模块创建一个简单的http服务器

成功搭建node环境后,利用node.js的http请求创建一个简单的HTTP服务器. 1.在你的项目的文件夹创建一个app文件,同时在文件夹app中创建app.js的node.JS文件.用任意编辑器都可以 2.在终端打开node app.js 指令,输入正确后悔看到屏幕上面输出信息:Server running at http://127.0.0.1:1337,表明已经成功启用本地的1337的接口http服务器 3.打开任意的浏览器,输入server服务器地址:http://127.0.0.1

创建一个简单的 MDM server(1)

前提:已获得 APNS 证书 ,已完毕 MDM 配置描写叙述文件的制作.请參考< MDM 证书申请流程 >一文和<配置MDM Provisioning Profile>. 环境:OSX 10.9.2,JDK 1.6.Eclipse JavaEE Helois,Tomcat 7.0 一.前言 <THE IOS MDMPROTOCOL>(即Inside Apple MDM)一文中描写叙述了一个简单 MDM Server Python 实现(server.py). 笔者也曾參

通过python 构建一个简单的聊天服务器

构建一个 Python 聊天服务器 一个简单的聊天服务器 现在您已经了解了 Python 中基本的网络 API:接下来可以在一个简单的应用程序中应用这些知识了.在本节中,将构建一个简单的聊天服务器.使用 Telnet,客户机可以连接到 Python 聊天服务器上,并在全球范围内相互进行通信.提交到聊天服务器的消息可以由其他人进行查看(以及一些管理信息,例如客户机加入或离开聊天服务器).这个模型如图 1 所示. 图 1. 聊天服务器使用 select 方法来支持任意多个客户机 聊天服务器的一个重要

IntelliJ IDEA 15 部署Tomcat及创建一个简单的Web工程

一.部署Tomcat 二.创建一个简单的Web工程 2.1创建一个新工程 创建一个新工程 设置JDK及选择Web Application (创建的是Web工程) 点击Next,选择工作空间,起个工程名 2.2项目部署 在工具栏点击 Project: 无需任何设置,选择默认编译目录(或自定义编译目录) Modules: 将Tomcat加入 Libraries:无需任何设置.这里描述了此项目的依赖. Facets: 无需任何设置.这里描述了此项目所适配的服务框架 Artifacts: 无需任何配置.

自己动手模拟开发一个简单的Web服务器

开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的Web服务器来体会一下. 一.请求-处理-响应模型 1.1 基本过程介绍 每一个HTTP请求都会经历三个步凑:请求-处理-响应:每当我们在浏览器中输入一个URL时都会被封装为一个HTTP请求报文发送到Web服务器,而Web服务器则接收并解析HTTP请求报文,然后针对请求进行处理(返回指定的HTML页面

使用 Nodejs 搭建一个简单的Web服务器

使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块.路径解析模块.以及301重定向问题,下面我们就简单讲一下如何来搭建一个简单的Web服务器. 作为一个Web服务器应具备以下几个功能: 1.能显示以.html/.htm结尾的Web页面 2.能直接打开以.js/.css/.json/.text结尾的文件内容 3.显示图片资源 4.自动下载以.apk/.

java实现一个简单的Web服务器

Web服务器也称为超文本传输协议服务器,使用http与其客户端进行通信,基于java的web服务器会使用两个重要的类, java.net.Socket类和java.net.ServerSocket类,并基于发送http消息进行通信. 这个简单的Web服务器会有以下三个类: *HttpServer *Request *Response 应用程序的入口在HttpServer类中,main()方法创建一个HttpServer实例,然后调用其await()方法,顾名思义,await()方法会在指定端口

使用 CodeIgniter 创建一个简单的 Web 站点

原文:使用 CodeIgniter 创建一个简单的 Web 站点 参考源自: http://www.ibm.com/developerworks/cn/web/wa-codeigniter/index.html 我的第一个 CodeIgniter 项目(除HelloWorld外),现整理记录下来. 相关环境: 系统:ubuntu-10.04.3 Apache:httpd-2.4.7 PHP:php-5.4.22 MySQL:mysql-5.6.16 CI:CodeIgniter-2.2.0 目标