Chinaunix首页 | 论坛 | 博客
  • 博客访问: 622716
  • 博文数量: 692
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 4715
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 13:38
文章分类

全部博文(692)

文章存档

2011年(1)

2008年(691)

我的朋友

分类:

2008-10-17 13:44:04

        背景:

        对于旧有系统的改造和升级,最苦恼的莫过于跨平台,跨语言。我的一个朋友最近从专向了专攻.NET——因为.NET的CLR既有类似虚拟机概念这种已经被证明很成功的底层托管能力。又对于的就有桌面应用提供了良好的兼容。

        最近我的一个个人项目也面临着这样的需求。一个C语言开发的中间件,通过API暴露给二次开发及插件应用。现在由于对其应用的需求变得日趋复杂,而且正在脱离Unix的管理环境,走向基于JWS这样的BCS管理。有朋友推荐我用JNI,但这样一是增加了耦合度,二是让Java睡在JNI感觉不太安稳。在认知了上下两层的系统平台后,问题变得明朗起来:如何在HTTP下实现Java和C之间的交互?

    思路:

        本人对Java比较熟悉,先从Java的角度入手,Java间的通信方法:

        1、通过URL,Applet/JWS访问被影射到URL的动态资源(Servlet)

        2、通过URL,Applet/JWS访问共享的静态资源(Server定期更新静态资源)

        3、通过序列化和反序列化,实现简单对象的传输(比如Resin的Hessian框架就提供了这种通信的方式)

        4、通过一些工具做代码生成,利用Web Services实现客户端和服务端的交互

        此外脱离HTTP,还可以做RMI,socket编程

        现在问题是通信的一端由Java变成了C/, 于是, 解决方案1需要把动态资源由CGI来定义,而方案3变得不再适用。于是方案有:

        1、通过URL,Applet/JWS访问被影射到URL的动态资源(CGI)

        2、通过URL,Applet/JWS访问共享的静态资源(Server定期更新静态资源)

        3、通过一些工具做代码生成,利用Web Services实现客户端和服务端的交互(×××这是我们讨论的重点×××)

        解决方案

        现在针对上文提出的3中通信方式中的1和3谈一谈实现的方法,2的实现方案比较灵活,需要发挥大家的想象力了:)

    针对CGI:

    首先CGI可以配置在各种主流的中作为后端的脚本运行。大家可能对Servlet更熟悉一些。

    CGI可以用脚本写,也可以用C来实现。CGI被触发后,通过系统的环境变量来获得输入,在处理完毕后向标准输出中输出结果。

    由此可以想见,Web在接受到来自HTTP的请求后,首先把请求的参数获取到,然后设置到环境变量里。

    根据对访问的URL的解析和服务器自身的配置,找到服务于请求的CGI程序的位置,然后执行这个程序。

    这个程序被执行后通过环境变量得到了服务器先前设置在环境变量中的参数。在经过一些复杂的逻辑操作后,向标准输出输出结果。

    这个输出又被Web服务器所捕获,转而传递回请求的客户端。

    更多关于CGI的知识和理解,大家可以通过google来寻找答案

    上述CGI的方式可以让我们直接获取到结果,但是方案比较原始和基础。其缺点有:

    1、 需要自己制定类型传输,做封装和拆封,否则只支持字符串

    2、 我们不会为了要用C的API就给它装一个或者自己实现一个Web服务器的,这让我们的底层程序显得蠢笨而冗余。我们希望能有一个超薄的Server外壳,在对API封装后,通过某个端口进行开放即可。

    针对Web Servcies:

    Based on上面的两个不足,我们只能把希望寄托在Web Services身上了,笔者在这里推荐给大家的是在C/很著名的Web Services工具gSOAP。大家可以到上去这个工具。

    通过这个工具,我们可以做到:

    1、 一个Stand-alone的服务器外壳

    2、 一个根据API程序自动生成的Web Services服务

    3、 一个WSDL描述符文件

    接着上次的话题,今天我们聊聊gSOAP这个框架,我们把用C写的旧有系统用gSOAP改造一下,通过SOA的形式发布出去。

    上文提到,利用gSOAP可以做到以下3点:

    1、 一个Stand-alone的服务器外壳

    2、 一个根据API程序自动生成的Web Services服务

    3、 一个WSDL描述符文件

    客户根据 WSDL 描述文档,会生成一个 SOAP 请求消息。Web Services 都是放在Web服务器后面,客户生成的SOAP请求会被嵌入在一个HTTP POST请求中,发送到 Web 服务器来。Web 服务器再把这些请求转发给 Web Services 请求处理器。请求处理器的作用在于,解析收到的 SOAP 请求,调用 Web Services,然后再生成相应的 SOAP 应答。Web 服务器得到 SOAP 应答后,会再通过 HTTP应答的方式把信息送回到客户端。

    WSDL是Web服务中客户端和服务端沟通的桥梁,描述了对象提供的方法。SOAP帮我们制定了一份被官方认可的对象的封装方法。有了WSDL,客户端只关心如何把参数用Soap封装起来发出去,并获取结果。服务端只关心如何对Soap进行拆包->服务->封包。gSOAP可以帮我们实现上述过程中的拆包和封包,而我们可以只关心服务的实现。

    言归正传,在这里我们以一个简单的实现加、减、开放的Web Services的服务为例子,介绍gSOAP的使用:

    为了发布这个Web服务,首先我们需要把服务的接口定义好,这个服务可能是一个现有服务的Adapter,为此我们定义头文件

 calc.h:
  typedef double xsd__double;
  int ns__add(xsd__double a, xsd__double b, xsd__double &result);
  int ns__sub(xsd__double a, xsd__double b, xsd__double &result);
  int ns__sqrt(xsd__double a, xsd__double &result); 
      

    注意到这里面我们把double定义成了xsd__double(两个下划线),这是为了告诉gSOAP,我们需要的soap格式和WSDL格式是基于 Document/literal的而非rpc/encoded.为了不把事情搞复杂,在这里我只能说,Java1.6自带的Web Services工具只支持Document/literal格式的WSDL,所以我们生成这种格式的WSDL。至于这两种格式之间选择和他们的long story,大家可以参考下面的文章:

   

    编写好头文件后,我们就可以利用gSOAP提供的工具进行生成了:

/usr/lib/gsoap-2.7/bin/soapcpp2 -S -2 calc.h
      

     

   

[1]  

【责编:Chuan】

--------------------next---------------------

阅读(327) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~