iOS 的围栏花园

许久以前看过一篇论文,将苹果公司移动操作系统的安全模型叫做 Walled Garden Model ,将 Android 平台的安全模型叫做 End-user control model 。这两种平台具有迥异的设计思想和与生具来的“种族差异”,很有意思。今天就来说说 iOS 的 Walled Garden,我将它翻译成“围栏花园”。

iOS 是一种严格的 Walled Garden

在维基百科中:

a “walled garden” refers to a carrier or service provider’s control over applications, content, and media on platforms (such as mobile devices) and restriction of convenient access to non-approved applications or content.

简单翻译一下,运营商或者服务提供商对平台(移动设备)上的应用、内容和媒体进行强势控制,限制非法的应用和内容。维基百科文中提到,iOS 就是典型的 Walled Garden 运作范例。

iOS 的围栏花园是一种“圈养”式的模型,这种圈养,不仅仅是对最终用户,更是对每一个应用。打一个比喻,用户就如一个孩子,被限制在一个周围围着高大围栏的安 全的活动范围里,而应用就像围栏花园中种的鲜花瓜果,这个花园的每一棵植物只允许生存在自己的花盆里,如果有邪恶的植物,比如毒花毒草企图污染泥土、空气 或者把根伸到其他花盆,那它将被苹果公司的园丁大叔连根带泥整个扔掉。于是,在园丁大叔的强制管理下,花园里的各种植物按照规划长得规规矩矩。花园里鸟语 花香,孩子在围栏花园中放心玩乐,如此和谐“世界”只因有一个神一样的存在——苹果公司,它打造花园、建立秩序、维护秩序,正如人类社会一样。这样的围栏 花园为一个核心的政府意志所主导,其规则被一整套审核机构进行强制推行。

每一个应用都是一个孤岛

“每一个应用都是一个孤岛(Every App Is an Island)”,苹果公司的开发文档如是说。在信息世界,其他设计师们都在想办法打破信息孤岛的时候,这个设计很值得思考,安全至上的移动操作系统,可 以说极大程度的推崇应用隔离,毫不客气的牺牲了本机内应用间信息共享(实际上,应用间的通信可以通过云端机制来解决大部分需求),可以说在同一台设备上, 应用间的距离是“咫尺天涯”。

Diametric scales-CS5

换一种严谨的技术语言来审视 iOS 上的应用安全性特性,苹果平台中的应用,被限制在沙箱(sandbox)中,应用只看到沙箱容器目录,不可见系统的其他目录和整个文件系统,沙箱中关键子 目录,例如,<Application_Home>/AppName.app、<Application_Home> /Documents/、<Application_Home>/Documents /Inbox、<Application_Home>/Library/等目录,每个子目录使用方法有严格规定。沙箱严格控制文件目录访问, 每个应用仅能访问自身的文件和数据,严格控制了硬件、系统共用数据、网络等资源的使用权限。如果应用不遵循设计规格,应用或者不能正常运作,或者在审核环 节被废弃,或者上市之后被下架。

ios_app_layout

有深入探究者会好奇,严格的沙箱结构下,应用只能访问沙箱的容器目录,应用之间的文件共享究竟需要多大的代价?举一个例子来帮助理解(非开发步 骤),EMail 应用和 TXT  编辑应用严格隔离,如果 EMail 的应用需要 TXT 文本编辑器打开和显示一个文本的附件,TXT 文本编辑器需要声明自身能处理的文档类型,当用户点击 EMail 的附件并选择了TXT文件编辑器的时候,EMail的TXT附件被 iOS 系统机制传送到 TXT 文本编辑应用的 /Documents/Inbox 目录下,TXT 文本应用读取这个附件文件展现给用户,当用户编辑这个文本附件,TXT 文本编辑应用应该将这个文件移动到本应用的数据目录下,因为沙箱规定/Documents/Inbox只有读取和删除文件的权限,并没有写文件的权限。这 是严格的沙箱结构的特例流程,苹果公司官方开发文档中需要专门文档进行阐述。

iOS 的沙箱不是Unix的应用隔离机制

iOS 和 Android 有一定的亲缘血统,这个血统来自于 Unix ,具有类似的进程账号绑定机制。Android 上使用不同的用户账号来运行进程,以此进行应用隔离,iOS 与此不同,所有应用使用相同的用户账号来运行进程, 使用沙箱内核扩展来实施安全隔离机制,iOS 内置了 35 个沙箱配置文件对应不同类别应用的运行。iOS 的沙箱机制可以参看 iOS 的同源兄弟 Mac OS X上的 “sandbox-exec”  命令,其运作机制可以参见下图(来自“技术奇异点”博客),在操作系统内核对应用访问权限进行强制检查,图中的 Access Control List 相当于 sandbox-exec 命令中的沙箱配置文件profile。

sandbox- exec  [- f  profile- file]  [ – n  profile- name]  [ – p  profile- string]  [- D  key=value  …]
command [arguments …]

2011-1214-Sandbox-Static

$  sandbox-exec -f /usr/share/sandbox/bsd.sb /bin/ls

使用沙箱环境运行程序/bin/ls程序,其沙箱配置文件为/usr/share/sandbox/bsd.sb。想体验一下沙箱的限制作用,可以运行下面的命令:

$ sandbox-exec -n no-internet ping www.google.com
PING www.l.google.com (209.85.148.106): 56 data bytes
ping: sendto: Operation not permitted

……

可以看到限制了网络的访问权限之后,ping 程序将不能正常运行。

Mac OS X上用户可以运行 sandbox-exec 命令,可以看到文件系统,以及控制沙箱,然而,iOS 上的沙箱则是无所不在的幕后黑手,沙箱就像是一方井水,应用就像是坐井观天的青蛙。

围栏花园是运营出来的

尽管 iOS 上具有严密的机制隔离以及控制应用,然而,再完备的操作系统也难免有漏洞,并非牢不可破。整个 iOS 围栏花园的应用安全不仅仅靠 iOS 操作系统本身的架构以及防卫体系,更加依靠苹果公司对整个平台生态系统的经营。

苹果公司通过终端(iPhone)与平台(应用商城 App Store 以及其他内容传送平台)的组合运营,逐步吸引和驯化用户,平台的应用和内容丰富了,成为用户获取应用和内容的主流渠道,因此用户也逐渐忠诚,于是,聚集了 海量高商业价值用户的平台成为苹果公司的筹码,得以要求逐利的应用开发商遵循苛刻的安全准则,平台安全性则反过来增加用户对平台的信赖程度,使整个生态系 统呈正反馈方向健康的发展。

在平台运营中,需要有足够的技术装备,还需要巨额的人力成本和资源。在应用上架之前以及任何时候对静态代码进行扫描,逆向工程,运行时检查,杜绝恶意的应用毁坏平台的安全根基。

开源项目中小云计算平台应用:呼叫中心

【IT168信息化】以Digium公司开源的软交换软件Asterisk为基础使用Freepbx作为交换机&呼叫中心Web管理系 统管理语音交互树和呼叫中心各个队列座席策略等,基于AsteriskJavaAMI接口自行开发一套CtiProxy座席代理软件,使用Flex技术实 现座席端队列动态显示控件,实现座席动态登录,退出。使用WEB集成本企业的CRM实现来电弹屏,电话来显记录及日常呼叫操作,降低了集成成本。使用快捷 键实现呼叫转移,三方呼叫,临时退出(恢复进入)队列,强插,监听等基本呼叫中心功能,基本满足了30座席400呼叫中心基本日常运作。

4.1 所用开源项目介绍

Asterisk( www.asterisk.org)

“Asterisk是一款实现电话用户交换机(PBX)功能的自由软件、开源软件。Asterisk提供完善PBX功能,可以连接多种不同的电话终端, 包括普通电话机,IP电话机,软电话等,支持多种主流的IP电话协议和系统接口。Asterisk软件提供很多以前只有昂贵的专业PBX系统才支持的功 能,比如:语音信箱,会议电话,交互式语音应答和自动电话转接等。由于该软件开放的性质,用户可以灵活的配置方便的扩展系统的功能,甚至编程开发自己所需 功能的模块。”摘自-中文维基百科。这里采用asterisk作为方案的基础是因为asterisk不但是VOIP CALLCENTER应用用户最多的开源平台,而且Digium公司提供了一系列的硬件设备为系统搭建提供稳定的支撑。这里作为模拟PSTN接入卡,采用 的是DIGIUM公司原装的TDM2400P转接卡实现24口FXS接入,为30座席模拟进线提供支持。

FreePBX( www.freepbx.org)

“FreePBX 是一个最强大的 GUI(基于网页的)配置Asterisk 的工具。FreePBX 之前被称为 Asterisk Management Portal,是 IP 电话工具 Asterisk 的标准化实现,可提供 Web 配置界面和其他工具。”摘自-中文维基百科。FreePBX作为最好的Asterisk配置工具,已经有超过300万个下载,截至本文发布版本也已经发展 到3.0。下图为FreePBX监控Asterisk工作状态的状态面板,能够显示相关的运行信息。

开源项目中小云计算平台应用:呼叫中心
▲图4-1

AsteriskJava (www.asterisk-java.org)

AsteriskJava 是一个使用java语言编写的一套通过使用Fast-CGI(基于tcp的asterisk 代理接口快速实现)或AMI(asterisk 管理接口)协议和asterisk进行通讯的一套SDK(基础开发类库)。使用AsteriskJava 能够实现监听Asterisk平台呼叫事件(实现客户端弹屏通知),座席登录退出,呼出或挂机等语音操作,实现了一个客户端通过网络操作Asterisk 的一个代理接口,为对Asterisk进行二次应用集成开发提供了很友好的跨平台解决方案。

4.2 30座席纯软交换呼叫中心系统搭建

开源项目中小云计算平台应用:呼叫中心

上图为系统基本架构,首先使用安装有TDM2400P的一台服务器安装FreePBX和Asterisk搭建呼叫中心系统,然后开发 CallCenterProxy(呼叫中心座席网关)及Flex座席控件集成WebCrm。具体搭建过程(IVR,ACD,QUEUE)请参考相关项目文 档或其他互联网公开发表文章,本文不再累述,本文着重强调在搭建过程中需要注意到的一些事项以及关键开发过程中遇到的一些技术问题解决方案。

4.2.1 动态座席

一个24*7正常运作的呼叫中心一般都是采用多班人次进行倒班来交替工作的,不可避免多个座席人员使用同一个座席来进行工作,也不可避免采用其他人的工 位进行临时工作,这时候座席动态化的需求就显而易见。动态座席是指座席人员使用客户端软件在登录的时候,指定自己的座席工号登录座席,座席人员本身通讯可 以使用纯电话软件,也可以采用座席所在的固定接入分机,有了动态座席的支持,那么座席人员可以灵活的机动选择临时工位办公。

开源项目中小云计算平台应用:呼叫中心

本方案动态座席,主要使用Asterisk本身所支持的agent特性,在多个队列(Queue)中设置Agent登录作为座席识别标识,只有使用 AgentLogin指令(AMI协议)登录到指定的队列才能真正实现座席在线,并可在随时使用AgentLogoff退出队列。下面介绍具体在 FreePBX中的配置。

首先配置Device,Users,Agent,全部使用分机号码进行关联。

开源项目中小云计算平台应用:呼叫中心

其次在Queue配置中,使用Agent进行配置,这样只有登录的agent才作为有效座席。

这里我们举例队列600为客服座席队列,811,812,813,823为客服座席,这里配置上使用的是A811-823来配置使用座席作为队列中的成员,并且当队列成员为空能够进行跳转到其他指定分机或队列,当座席成员为忙状态能够自动分配到空闲的座席。

4.2.2 自动报读座席工号

座席工号是为了方便统计客户服务质量而设计的,一方面为了在于客户沟通过程中能够方便用户能够投诉或反映座席工作态度质量,一方面在后台进行工作分配的 时候有能够快速标识座席人员。所以在客户被接听的第一时间首先自动报读座席工号,是一个呼叫中心运营水平的基本体现。这里我们使用asterisk- 1.4.23.2版本作为基础进行定制修改,采用自定义拨号规则和修改QUEUE源代码实现。

开源项目中小云计算平台应用:呼叫中心

首先在extention_custorm.conf 增加自定义的语音读报工号的拨号规则,同时把录制好的queue-report-agentid-1和2都要防止在默认录音文件存储目录,然后再修改 asterisk-1.4.23.2/apps/app-queue.c,在callqueue定义部分首先定义参数,默认开启报读工号功能 unsigned int baohao:1; 在trycalling函数内部/* Stop music on hold */和/* If appropriate, log that we have a destination channel */中间处增加如下调用自定义的报号规则代码:

开源项目中小云计算平台应用:呼叫中心

修改完代码,需要编译安装一遍定制的asterisk。

4.2.3座席端Flex控件集成WebCrm

要想实现座席端控件的基本功能,必须首先实现代理服务器作为AMI呼叫事件的动作侦听,同时实时与座席端控件进行通讯。

开源项目中小云计算平台应用:呼叫中心

CallCenterProxy服务器端使用java开发一个FlashCtiBarServer服务器,侦听flexsocket认证端口843,如 果有flex客户端连接就产生一个Adapter,通知客户端的通讯安全策略认证通过,proxy通过实现 AsteriskServerListener,ManagerEventListener来侦听asterisk本身的各种事件动作,底层基于 AsteriskJava实现。

客户端控件使用Flex开发,基于Flex sockt技术,直连CallCenterProxy,并维持心跳通讯保持在线。Webcrm使用一个url来直接集成座席控件,使用url通知座席上 线,服务器端根据座席端通讯在一段时间内没有通讯自动下线退出队列。客户端控件使用flex向上呼叫javascript来实现url参数和自定义方法的 绑定,包括弹屏的url等信息可以实现动态设置。

//set the javascript can callback method set the parameter

ExternalInterface.addCallback(“setAgentid”,setMonitorAgentid);

ExternalInterface.addCallback(“setPopBase”,setPopBaseUrl);

ExternalInterface.addCallback(“setMornitorQueues”,setMornitorQueues);

ExternalInterface.addCallback(“connect”,connectToServer);

//call the javascript method to set parms And start connect server

ExternalInterface.call(“startclient”); 

开源项目中小云计算平台应用:呼叫中心

以下为WEBCRM呼叫弹屏界面

开源项目中小云计算平台应用:呼叫中心

在本方案中着重描述了关于web控件集成,动态座席等一些特定应用场景,其他一些通用呼叫中心功能特性配置,请自行配置,包括录音文件的按日期分目录转 存成mp3等请参考作者博客。本系统开发完成在2009年7月,最开始只有12座席,发展到目前30座席10并发话路,曾经连续稳定运营4个月未服务器重 新启动,只是用一台奔腾双核cpu的pc机,cpu平均使用率只有5%,峰值30%左右,来去电弹屏和座席登录只做了非常小的修改就完成系统集成,为以后 扩充高一个数量级的呼叫中心提供有了一定的借鉴意义。

作者介绍:

·Tony汤文志 目前供职于中卫莱康任系统研发部总监兼IT支持部总监10年无线互联网软件研发经验,曾供职于多家无线互联网企业包括华友世纪(Nasdq:HRAY),搜狐 (Nasdq:SOHU)负责无线互联网研发工作,参与多个电信级的运营商无线增值平台的开发。2007年进入远程健康管理企业中卫莱康负责远程心电监护 平台的研发和系统支持工作,在远程健康管理平台建设过程中应用各种开源项目,积极推动开源项目的推广使用,倡导中小企业优先应用开源项目搭建支撑平台。点击作者微博 博客 邮件 

·Frank 赵杰 目前供职于中卫莱康 任it支持经理 参与本文邮件方案和监控方案编写

用 Unix 的设计思想来应对多变的需求

无论是Unix设计,还是面向对象设计,还是别的什么如SOA,ECB,消息,事件,MVC,网络七层模型,数据库设计,等等,他们都在干三件事——解耦,解耦,还是解耦!所谓解耦,就是让软件的模块和模块间尽量少地依赖起来。

现实当中的例子

让我先举几个现实生活中的例子:

1、现实社会中,制造灯具的工厂完全不关心制造灯泡的工厂,制造灯泡的工厂完全不关心制造灯具的工厂,但是,灯泡和灯饰可以很完美地组合成用记所喜欢的样子(这和@weidagang 在“需求变更和IoC”说到的那个PC的例子相仿)。他们是怎么做到的?

2、互联网上,做网站的人完全不用关心用户在用什么样的操作系统,什么样的客户端浏览器 (当然事实上,浏览器的不标准让网站那边很头痛,这里只是举个例),反过来,上网的人也不关心做网站的人在用什么的技术开发网站。但是大家在完全不关心对 方的情况下,可以很正常地协同工作在一起。为什么?

 

这样的例子太多了。为什么可以做成这样呢?因为大家依赖的是一个接口,灯具和灯饰并不互相依赖,他们依赖的是一个接口,做网站的人和浏览网站的人依赖的还是接口——HTTP协议。这就是面向对象的核心思想——依赖于接口而不是实现,这就是解耦。当你看过这两个例子以后,我希望你以后设计的软件至少不能比我们现实社会中的这些方法要差。不然,你就是在让社会倒退了,呵呵。

你会说,这和Unix,和应对需求变化有什么关系?好让我们再来看一下Unix的设计。

Unix设计的例子

下面是几个Unix下的例子:

1、Unix下,所有的硬件都可以通过文件的方式存取。其统统在/dev下。于是,软件 和硬件的耦合被解开了,操作系统只需要把硬件统统变成文件,而程序只需要使用三个东西,一个是fd,一个是read(),一个是write(),就可以来 操作任意的硬件了,这就是抽象,简单到不行。

2、Unix下,所有的命令都可以用管道串起来(管道绝对是个伟大的发明),这样,所有 的命令间的交互全部解耦到只依赖于STD_IN, STD_OUT设备上。最酷的是,用户可以使用管道任意地拼装那些命令,以完成各式各样的功能。管道这个设计思想可以映射为今天的Web Service,你可以任意地拼装各种Web Service。

看到这里,你会发现,这还是解耦,本质上来说,也是一种依赖倒置——OOD的精髓。但是,Unix还不仅仅是这些。我们再来看几个例子:

1、Unix下,软件都是绿色地安装。在iOS上更明显——各个程序间基本上互不干扰,这个程序产生的垃圾文件不会影响到另一个程序。你删到一个程序不会让另一个程序不举,各是各的空间。你可以删除这些程序,只要把内核心留着,系统照样可以启动。

2、Unix下,你可以通过设置一些环境变量,让多种环境同时存在,比如:某个LAMP 用的是Apache 2.0, Mysql 4.0, PHP 4.0,某个LAMP用的是Apache 2.2, Mysql 5.0,PHP5.3,你不但可以方便地在系统中切换这两个环境,你甚至还可以同时启动他们。

3、Unix下,你可以随意地替换你想要的程序。比如,你不喜欢bash,你可以替换成ksh/csh等,你不喜欢awk,你可以替换成gawk,所有的东西都像零件一样,你不喜欢什么,你就可以替换什么。

这三个例子告诉了我们——当你把你的软件设计地耦合度非常地低时,你可以随意地组合,随意地安排你的系统。想当的灵活,灵活到Windows到今天都学不会。

应对需求变化

看到这里,你可能明白我想说的是什么了,你可能开始觉得怎么样的系统设计会更有效了。如果你还记得《Steve Y 对平台的长篇大论》,你就会知道我想说什么了。是的,我想说的就是,当你真正了解了Unix的设计思想后,你会觉得今天的这些东西都是对Unix设计思想的一种传承或是变种。这种东西就是:

1)解耦,解耦,解耦。尽量地让你的模块不要在实现上耦合,而是耦合某个规范,某个标准。

2)KISS,KISS,KISS。要做到高度解耦,你的模块就一定要很简单,当然不是说简单到只有几行代码,而是简单到只干一件事,并把这件事干到极致。然后通过某个标准拼装起来。

3)拼装,拼装,拼装。我想不起来是谁说的了,这句 话是这样的,当我想用一个模块的时候,我直接调用就好了,没有必要像C或Java一样,还要编译。是的,拼装需要一个框架,需要一种标准协议,然后让所有 的系统都耦合在这种规范上,各自独立运行,就像一个机器上的各个部件一样,当我觉得这个部件不爽,换了就是了。(例如,当我们在尝试不同的算法的时候)

想想建材和家俱市场,无论用户过来想装修什么,我都可以满足用户的不同需求,只要你是和家装相关,我基本上都能满足你,不是吗?无论你怎么变,只要不变态,我基本上都可以满足你。这就是解耦,拼装带来的好处。

你可能会说我说得太简单了,另一方面,你可能觉得有一些系统这样做没必要,我承认,不过,你可以有选择的或多或少地试试。(其实,我相信你已经在不自觉得或多或少地使用这种方式开发软件了)

8个新鲜好用的 jQuery 插件

1) Glisse

Glisses.js 是一个简单的交互式的可以定制 jQuery 照片浏览器。你将喜欢它的纯 CSS3 图片切换方式。

2) Touch Gallary

这个插件可以将网页上的一系列照片转换成适合触摸屏的照片库。它可以在所有主流浏览器中工作,除了 IE7 及其以下版本。最重要的是它为 iOS 和 Android 做了特别的优化。

3) Wookmark jQuery Plugin

4) Real Shadow

这个插件可以创建非常真实的阴影效果。非常适合做 demo 或者首页。

5) Stellar.js

6) jQuery Transit

7) Nail Thumb

这个插件可以为高分辨率的图片创建缩略图,而不会有任何变形,只需要一行代码。

8) Slab Text

把一件小事做完

我每天都在Hacker News上阅读各种创业故事,我订阅了Jeff Atwood精彩的Coding Horror编程博客,在StackOverflow上 查看人们的个人信息。每次我进入某个人的“关于”页面,上面总是说“你好!我是X,Y的创建者”。总有一个他们开发的公共作品可供他们谈论。我也想成为这 样的人。我作为软件开发者的时间并不是很长。我以一个学生的身份在因特尔干了3年,开发内部软件。我目前的工作仍然是开发内部软件。没有什么可向世人展示 的。

你好!,我是Amir Rachum,我是创造了??? 

我想做出点什么。不需要很大,但一定要完成。这些年我开始过很多工程,但大部分都未能完成。难的、算法部分的是有趣的。完完全全做完,不那么有趣。

目前,我在做一个安卓版的Cloud 9游 戏。实现这个游戏并不困难。它很有趣,很简单,我的目标是完成它,发布它。为了从心理上促动自己,我在谷歌的安卓交易市场上创建了帐户,并支付了开发者帐 号的费用。那好,这回我是真的了。对一个简单的游戏的一个简单的实现不是一个什么令人自豪的事。我希望从中获得的是做出一个产品的能力和经验,看看这是一 种什么感觉。我希望这次经验能帮助我在以后做出更重大的东西。祝我好运。

附录.这是我的用户界面的样子(正在开发过程中):

游戏原型界面

 

本文转载自外刊IT评论,原文标题《事业有成》,在这里我改成了《把一件小事做完》