一、写在最前由于本人的技术水平有限,难免会出现错误。本文对任何一个人有帮助都是我莫大的荣幸,任何一个大神对我的点拨,我都会感激不尽。 二、技术选型在2013年8月低的时候,公司中了XXX市场监督局肉品配送车辆监控的项目。整个系统软件部分需要实现的功能不难,最大的难点就是服务器的系 统要求是Linux的,其次就是10月底系统能够初步成型。由于之前做的车辆监控系统都基于Windows的,要在短时间内完成这个项目,于是Mono就 成了我的首选。张善友的 博客,也成了我经常光顾的地方,后来通过跟张哥的一番沟通。最终采用了张哥推荐的方案,数据库使用PostgreSQL,Web服务器使用国产的 Jexus,Linux操作系统使用CentOS6.2(这个是客户要求的)。其他都可以很好移植,之前的系统前台使用的 Extjs+SilverLight+Asp.net,服务层使用的WCF,当时张哥有提醒我Mono下的WCF坑特别的多,ORM使用的是 Nhibernate,地图引擎依旧采用的DeepEarth。有张哥的点拨,我的信心满满的。看上去似乎我需要解决的问题就是搭建好Mono环境,搞定 Mono下的WCF服务就可以大功告成了。 三、环境搭建装Linux系统,配置Mono环境,安装Jexus。写了个简单的Silverlight + WCF的程序部署到Jexus,竟然成功跑来了,当时的我偷笑了。然而,当我真正把系统部署到Jexus上面,才知道噩梦才刚刚开始。登录页面都没有过不去,此时估计很多人都会想要是在Linux下能Debug就好了,我也不例外。于是乎,我就折腾MonoDevelop,安装过程中遇到各种奇葩问题,而且不支持SilverLight的项目,我放弃了。采用最原始的办法,写日志。经过几天的折腾,终于可以跑起来了。 四、WCF攻克由于在折腾WCF的时候,遇到的默默其妙的问题比较多,有些能够通过Google搜索到。我这里就列举三个。 1:寻址版本 AddressingNone不支持添加 WS-Addressing 标头。如果你的WCF部署在IIS下能正常的调用,而部署在Jexus下确抛出这种异常。 检查项目下引用的dll,估计某些dll在Mono下支持不是很好。在有可能出错的异常写日志,而不要抛出这个异常。比如下面这个简单的例子,FluentNhibernate在Mono下的支持就不是很好。 public IList 2:客户端反序列化失败 当我把WCF部署到Jexus,成功生成本地代理后,调用WCF就会一直报这个错误。究其原因,就是因为生成代理类的属性指定了反序列化的顺序,而服务端我是没有指定的。所以,先把WCF服务部署到IIS下,然后客户端地址指向部署IIS的WCF服务,重新更新服务,再把配置文件中地址指向部署在Jexus的WCF服务即可。 Jexus下Host的WCF服务生成的本地代理: [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, Order=1)] public string CustomerCode { get { return this.CustomerCodeField; } set { if ((object.ReferenceEquals(this.CustomerCodeField, value) != true)) { this.CustomerCodeField = value; this.RaisePropertyChanged("CustomerCode"); } } } IIS下Host的WCF服务生成的本地代理: [System.Runtime.Serialization.DataMemberAttribute()] public string CustomerCode { get { return this.CustomerCodeField; } set { if ((object.ReferenceEquals(this.CustomerCodeField, value) != true)) { this.CustomerCodeField = value; this.RaisePropertyChanged("CustomerCode"); } } } 3:WCF服务导致Jexus的httpd worker不断重启 这个问题是困扰我最久的,在IE11下最为明显,Service.svc文件的post请求,动不动就被Pending。在最开始我不知道Jexus一直在重启,因为我看jws.log中没有Jexus重启的日志。后来得知可以通过 ps –ef | grep jws 指令可以查看进程的启动时间,如下图所示,可以看到httpd worker进程不断的重启。 |