本文的目的,旨在谈谈如何解决ITK的远程访问问题。
问题由来:在很多时候,我们都会面临Teamcenter与其它系统交互的问题,而在规范管理中,通常是不允许Teamcenter客户端直接去访问非Teamcenter服务器,此其一;在Teamcenter中,所有的前处理和后处理,以及handle,都是依赖ITK开发,而这些操作中,有时候需要推送数据到其它系统,或者从其它系统获取一些数据(比如编码),这些都需要ITK做远程访问,此其二。
解决思路:
思路一:将C/C++问题,转为其它语言的问题,比如:Java或者Python。做法如下:1)先用Java或者Python中写好访问请求,处理好返回结果,最后将写好的源代码生成可以在操作系统中独立执行的程序;2)在ITK代码中,使用类似system()函数,来调用之前生成好的程序。
这个思路,可以达到业务目的,但有两个致命的缺陷:1)不同的操作系统,调用可执行程序的方式不一样,存在兼容性问题。而且这种调用,是依赖操作系统Shell进行跨进程调用,可靠性方面可能会存在问题;2)维护很麻烦。不论是维护相关配置,还是维护代码,都是一个比较麻烦的事情。
思路二:直接在C/C++中引用远程访问库。早期可能更多地使用libcurl库,这个库的功能很强大很全面,但使用起来比较繁琐。近期可能更多地使用gsoap库,为啥?因为我们绝大多数,都只需要基于soap协议的传统WebService访问或者基于restful风格的service访问,而gsoap在这方面做得很省事。gsoap主页:https://www.genivia.com/dev.html
关于gsoap的使用方法,是目前一种比较流行的做法:1.通过命令行,使用gsoap提供的命令,生成C/C++代码;2.将生成的C++源代码,以及需要的支持代码(一般都能在gsoap中能找到),复制到ITK项目中;3.编译调试ITK。
gsoap调用参考:
std::string new_ablaze_id(const char* url, char* xml) {
std::string ablaze_id("");
ablaze::_ns1__getCode_USCORENormal request;
ablaze::_ns1__getCode_USCORENormalResponse response;
request.xml = xml;
ablaze::TcWsServiceSoap11BindingProxy* ablaze = new ablaze::TcWsServiceSoap11BindingProxy(url);
int ifail = ablaze->getCode_USCORENormal(&request, response);
if (SOAP_OK != ifail) {
ablaze->soap_print_fault(stderr);
}
else {
ablaze_id = response.return_;
}
ablaze->destroy(); // don't worry, 'response.return_' will be free.
delete ablaze;
return (ablaze_id);
}
思路三:绝大多数时候,我们都可以依赖思路二来解决业务问题。但有时候,会存在情况:1)需要访问的外部服务器太多了;2)开发人员对C/C++不够熟悉。这种情况下,我们可以考虑设计一个较为复杂的Teamcenter辅助系统来完成集成的需求,而ITK的所有远程调用,都可以通过这个辅助系统来完成,这样就可以大大减少ITK的编码量。如果我们把这个辅助系统放在Teamcenter服务器上,那么,很多和其它复杂系统集成的业务逻辑也可以统一。访问的大致过程如下:1.ITK--->辅助服务器-->其它服务器(含Teamcenter和非Teamcenter服务器);2.Teamcenter客户端-->辅助服务器-->其它服务器。
关于这个辅助服务器,我个人推荐使用Spring Boot + Teamcenter SOA实现。