OMS开发随笔之概述

上一篇中,介绍了OMS的特点和基本的开发概述,这篇详细谈谈具体在实践中遇到的问题及解决方案。本文之涉及到普通短信的开发,不包括彩信。

 

OMS的开发要点

总的来说开发oms没有太大的困难,毕竟只有四个接口,参数也不是很复杂。强烈建议在服务端的代码中加入日志功能以便调试。在实际操作上遇到的问题如下:

GetServiceInfo的返回值说明

对于GetServiceInfo的返回值中某些属性的意义,做一下说明,详见官方文档:

  <supportedService>
    <!--maxRecipientsPerMessage:最多多少个收件人-->
    <!--maxMessagesPerSend : represents the number of separate SMS messages allowed in one xmsData. -->
    <!--maxSbcsPerMessage : 每条短信的字数 US ASCII characters-->
    <!--maxDbcsPerMessage : 每条短信的字数 双字节文字-->
    <SMS_SENDER
      maxRecipientsPerMessage="50" maxMessagesPerSend="20"
      maxSbcsPerMessage="128" maxDbcsPerMessage="70" />
  </supportedService>

这些值是由服务端设定的,对于serviceInfo整个内容可以用一个固定的xml文件存储,服务端程序只要简单的读入并返回给客户端即可。上面提到的四个属性值,会影响Outlook客户端的行为,比如短信预览时分页显示等。

这里特别注意:<serviceUri>字段的值一定要保证和用户在客户端输入的Uri完全一致,否则Outlook即使调用GetServiceInfo成功后发现服务端返回的这个Uri和用户输入的不一致也会报错,并将这里的Uri替换掉用户输入框中的Uri。

 

序列化和反序列化对象处理传入和传出

官方文档定义的四个接口无论是参数还是返回值都是C#的string类型(C++的话我想应该用std::wstring)。然而,这里的参数都是xml格式的字符串,服务端需要解析。如果使用C#开发ws的话官方给出了xsd的schema,只要将其拷贝下来保存成.xsd,然后用xsd.exe生成对应的class(xsd.exe xsdfile.xsd /c),就可以使用XMLSerailer方便的序列化和反序列化。可以参考下面代码作序列化和反序列化:

private static string XmlSerializer<T>(T serialObject) where T : class
{
    XmlSerializer ser = new XmlSerializer(typeof(T));
    System.IO.MemoryStream mem = new MemoryStream();
    XmlTextWriter writer = new XmlTextWriter(mem, Encoding.Unicode);
    ser.Serialize(writer, serialObject);
    writer.Close();

    return Encoding.Unicode.GetString(mem.ToArray());
}

private static T XmlDeserialize<T>(string str) where T : class
{
    XmlSerializer mySerializer = new XmlSerializer(typeof(T));
    StreamReader mem2 = new StreamReader(
            new MemoryStream(System.Text.Encoding.Unicode.GetBytes(str)),
            System.Text.Encoding.Unicode);

    return (T)mySerializer.Deserialize(mem2);
}

 

对于官方给的XML schema

DeliverXms的参数xmsData格式复杂,返回值string的格式也有些麻烦,然而,当我在代码中构造一个XmsResponse,并序列化成xml返回给Outlook时,Outlook确说发送失败,仔细比对发现,序列化生成的xml文档多出了两个类似名字空间的东西,无奈只能在代码里面手动构造XML文档返回。

结论:对于输入参数xmsUser和xmsData可以使用schema和由此生成的类,并结合反序列化成对象,来读取outlook发送过来的信息。对于输出参数,还是老老实实手动构造xml吧。

 

OMS的部署要点

 

上面多次提到OMS开发不困难,但是部署很麻烦,尤其是对笔者这样之前没有任何web部署经验的人来说更为痛苦。

看了无数遍的错误提示

在ws开发完之后,便需要部署并测试,点击Test Account Settings当然是需要过的第一关,但是在测试过程中,下面这个错误我已经记不清弹出过多少次了,每当看到这个错误的时候总是很失落,因为这个错误根本不能为我们提供什么有用的信息,强烈建议Outlook可以写入一些相应的日志,方便开发人员查看ws部署到底错误在哪里。

image

错误1

http还是https

如果不仔细看文档,不会注意到开发的ws需要使用https协议,需要提供SSL加密通信支持。如果在设置的时候输入的URL是http开头的,outlook不会尝试连接服务端,并会给出如下错误提示:

image

错误2

固然,作为一个在网络环境中交换敏感信息的软件,理所当然需要考虑到安全的问题,但是我们觉得也不该“一棒子打死”,如果这个ws是部署在某企业的内网环境中,不用考虑传输安全的话,根本没有必要使用https,因为这样会提高部署和乃至开发的难度。我们觉得也许这里启用一个选项会是个不错的主意。

基于这个原因,我们在部署ws的时候需要绑定https,证书和SSL。 

 

证书?证书!

在这之前我对CA和证书没有什么概念,只知道在访问有些https的时候浏览器总是提示威胁啊什么的。在做这个应用的时候算是理解了些东西(关于CA和证书参见浅谈https\ssl\数字证书)。Outlook必须服务端提供一个受信任的证书,可以用IIS7管理工具生成一个自认证的证书。这个证书是以机器名作为颁发者的,在IE的证书认证系统中,一个证书被检验三个方面的东西:

  • 证书是否是受信任的
  • 证书是否过期
  • 证书的颁发者是否和访问的主机具有相同的名字

这三个条件只要有一个不符合,IE8就会弹出威胁提示。在浏览网页的时候可以点“继续访问”,地址栏随机变成红色。但在Outlook中,这三个条件必须都符合才能受信任。

对于第一个条件,只要把证书导入到客户端IE浏览器的Trusted Root Certification Authorities下就会可以了。当然其中已经包含了一些权威的认证机构的证书。如果有能力去这些机构申请一个证书的话,你的证书将成为他们证书的子证书,无需将证书导入客户端,同样可以受信任。

对于第二个条件,过期了我想只能重新弄一个。

对于第三个条件,由于IIS7管理工具生成的自认证证书是以机器名作为颁发者的,所以在outlook客户端的设置中,必须以机器名作为主域名,不能使用IP地址。

在IIS7+部署https站点

部署一个oms站点跟部署一个普通的https站点没有什么区别,建议测试的时候先使用浏览器,当浏览器可以完全信任的访问这个站点的时候,再测试Outlook客户端。同时在服务端方法的调用过程中通过写log的方式可以方便的跟踪方法的调用。如果GetServiceInfo没有被调用,那么一定是https站点设置问题。下面以windows server 2008 r2作为例子简要说明:

Window server 2008 r2使用Roles来管理服务器服务组件,首先需要激活IIS:添加一个Role,选择Web Server(IIS)

clip_image002

在选择IIS附属组件的时候,记得勾选ASP.NET支持。然后一路下去即可。

发布你的ASP.NET web service,如果基于.net 4.0,还需要安装.net 4.0,并使用aspnet_regiis –i 命令设置IIS。

  • 在IIS管理工具中新建一个站点

clip_image003

物理路径指向发布的站点的路径。先使用http绑定,为了不和默认站点重复,使用8082端口。新建成功后如下图:

clip_image005

对于匿名用户访问站点的权限设置挺麻烦的,偷懒的做法:双击IIS中的Authentication,编辑Anonymous Autherntication,改成Application pool identity。

然后,来到Application Pools,选择站点使用的应用程序池,点击右侧的高级设置,修改Identity属性,选择LocalSystem。

clip_image006clip_image007

现在用服务器上的浏览器访问站点的.asmx文件应该能看到web服务方法列表页面。适当设置防火墙,使外部可以通过浏览器访问站点。

 

上面提到oms必须绑定成https的站点,所以我们的站点必须绑定https,关于更多https的基础知识,可以参考浅谈https\ssl\数字证书

  • 创建服务器自签证书

单击IIS管理器右侧的本机图标,双击右侧的Server Certificatin,进入到如下页面

clip_image009

点击右侧的Create Self-Signed Certificate

clip_image010

填入任何字符,比如“oms”。Ok。这样就会产生一个自签的证书,如下图。

clip_image012

编辑站点的绑定,选择https方式,端口保留443。选择刚刚生成的证书:oms。

clip_image013

双击右侧的SSL Settings,勾选Required SSL,忽略客户端证书,Apply。

clip_image015

这样站点就绑定的https,http方式将无法继续访问。用浏览器通过https访问.asmx。如下界面表示设置https成功,继续访问即可看到web服务方法列表

clip_image017

  • 导出服务端证书,安装在客户端

客户端安装服务端自签证书,再次进入站点绑定对话框,选择https那个编辑:

clip_image013[1]

点击View,查看证书,切换到details

clip_image018

点击Copy to File,进入证书导出向导,在如下页面选择do not export the private key。

clip_image019

按照向导导出证书,并将证书拷贝到客户端,在客户端把证书安装在“受信任的根证书颁发者”中。

clip_image020

在客户端浏览器测试https站点,如果能畅通无阻的访问,那么已经成功了一半了。

在Outlook客户端配置中输入https站点地址,注意这里不能输入ip地址,必须是机器名,然后点“测试”。如果服务端代码没有任何问题的话,就能立刻成功,但通常都比较困难,但是如果你写了log的话,只要能证明GetServiceInfo被Outlook调用了,那么就说明站点的部署成功了,随后就是参照上文提到的各种注意事项,小心调试了。

clip_image022

在windows server 2003上用IIS6部署基本思想和步骤差不多,就是要注意匿名访问权限的设置。在绑定自签证书的时候有所不同。需要安装服务器证书机构服务,推荐直接绑定服务器根证书,然后把根证书发放给客户端。

 

总结

通过OMS的开发,其实不仅仅收获了Outlook的一种扩展服务的开发方法,更多的是熟悉了IIS,熟悉了Web站点的部署。实际在操作中遇到很多问题,比如容易忽略的防护墙设置,匿名访问权限等。有时间要好好学习一下网络方面的知识了。

劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2011/01/13/oms-develop-deploy.html