主要是关于python的webservice,以及打包cxfreeze/pyinstaller。
使用pyinstaller为佳,有些soaplib的库cxfreeze需要特别设置。
- 安装Centos6.0。
若虚拟机,则内存需设为768M以上,否则无法进入图形模式,而在text模式下无法选择软件包集合。
选择development,安装下来有5G左右。
python为2.6.5。
- 安装pyinstaller:
wget http://files.zibricky.org/pyinst/pyinstaller-1.5.1.tar.bz2
tar xf pyinstaller-1.5.1.tar.bz2
cd pyinstaller-1.5.1
python Configure.py
- 安装soaplib。ZSI依赖的pyxml已经停止更新,不支持2.6以上的python。
sudo easy_install soaplib
#若lxml安装过于缓慢,可以手动安装
wget http://lxml.de/files/lxml-2.3.2.tgz
tar xf lxml-2.3.2.tgz
cd lxml-2.3.2
make
python setup.py build
sudo python setup.py install
- 删除selinux,关闭防火墙,其他机器能访问该机器的webservice:
sudo yum remove -y selinux*
/etc/init.d/iptables stop
sudo /sbin/chkconfig iptables off
# reboot
sudo init 6
- 新建服务器端文件
mkdir ~/lab/ws -p
cd ~/lab/ws/
vi test.py
- 其中,test.py的内容如下:
import soaplib
from soaplib.core.service import rpc,DefinitionBase,soap
from soaplib.core.model.primitive import String
from soaplib.core.server import wsgi
class MyService(DefinitionBase):
@soap(String,String,_returns=String)
def sayHello(self,msg,time):
return 'success:%s,%s'%(msg,time);
if __name__=='__main__':
try:
from wsgiref.simple_server import make_server
soap_application = soaplib.core.Application([MyService],'winlin')
wsgi_application = wsgi.Application(soap_application)
server = make_server('',7789,wsgi_application)
server.serve_forever()
except ImportError:
print "Error: example server code requires Python >= 2.5"
- 编译服务器端:
cd ~/lab/ws/
python ~/tools/python/pyinstaller-1.5.1/Makespec.py test.py
python ~/tools/python/pyinstaller-1.5.1/Build.py test.spec
- 启动服务器端:
cd ~/lab/ws/dist/test/
./test
- 编写C#客户端,添加webservice地址为http://10.12.12.105:7789/winlin?wsdl,内容如下:
#导入地址:http://10.12.12.105:7789/winlin?wsdl
using System;
namespace PythonWS
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(
new Winlin.ApplicationClient().sayHello(
new Winlin.sayHello()
{
msg = "CSharp client",time = "2011-12-25"
}
).sayHelloResult);
}
}
}
- END。
注意,复杂类型的字段不能写成类型的函数,否则否则soaplib在serialize时会报错:
TypeError: coercing to Unicode: need string or buffer,builtin_function_or_method found
例如,如此定义一个复杂类型,字段为str,名称为format(str正好也有format这个函数):
class MyClass(ClassModel):
format = String
在调用“subvalue = getattr(inst,k,None)”时获取该字段就是一个函数,而不是数据,所以报错。改成其他的名字就可以了:
class MyClass(ClassModel):
output_format = String