Python Pyro4 - Python Remote Objects

在线文档: [url]http://pythonhosted.org/Pyro4/intro.html[/url]

[b]Pyro4[/b],全名Python Remote Object。
学习这个库主要是因为工作需要在Java中调用Python。Pyro库的主要作用是让我们的应用可以在network下相互通信,是个轻量级的库。对于返回值的类型支持强大。并且Pyro是100%用Python写的,兼容任何版本的Python,包括3.x。
Pyro4发布超过15年了,而且现在还在持续更新。

关于Pyro4的特点,上文中的在线文档首页列了27条,就不一一列举了。生产环境有用到,并且没有出现过任何问题。

[b]前提,需要先Install Pyro4 module: [/b]可以通过pip工具进行下载安装。
Mac OS系统自带Python2.7,不过我自己又装了Python3.6,于是对应的pip命令也默认变pip3,具体如下:
>pip3 -V
>pip 9.0.1 from /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages (python 3.6)
>pip3 install Pyro4

Log表明已经装好: Successfully installed Pyro4-4.56 serpent-1.19

[b][color=blue]示例1: python server <---- python client[/color][/b]
例子在Pyro4的官网首页上就有,我这里只是拷贝测试下:

Server端代码: # saved as greeting-server.py

import Pyro4

@Pyro4.expose
class GreetingMaker(object):
def get_fortune(self, name):
return "Hello, {0}. Here is your fortune message:\n" \
"Behold the warranty -- the bold print giveth and the fine print taketh away.".format(name)
daemon = Pyro4.Daemon() # make a Pyro daemon
uri = daemon.register(GreetingMaker) # register the greeting maker as a Pyro object
print("Ready. Object uri =", uri) # print the uri so we can use it in the client later
daemon.requestLoop() # start the event loop of the server to wait for calls

运行后,输出: Ready. Object uri = PYRO:obj_73fa03c1a27b482195612fcd66357b3a@localhost:58672

客户端: # saved as greeting-client.py

import Pyro4

uri = input("What is the Pyro uri of the greeting object? ").strip()
name = input("What is your name? ").strip()
greeting_maker = Pyro4.Proxy(uri) # get a Pyro proxy to the greeting object
print(greeting_maker.get_fortune(name)) # call method normally

运行后(若报错Connection refused,请看下文的问题1):
What is the Pyro uri of the greeting object? PYRO:obj_73fa03c1a27b482195612fcd66357b3a@localhost:58672
What is your name? allen
Hello, allen. Here is your fortune message:
Behold the warranty -- the bold print giveth and the fine print taketh away.


[b][color=blue]示例2: python server <---- java client[/color][/b]
这里用到一个第三方库叫[b]pyrolite-4.10.jar[/b](最新版本是2017-02,v4.18),具体在线资源如下:
Github(大量例子及源码): [url]https://github.com/irmen/Pyrolite[/url]
在线Python文档: [url]http://pythonhosted.org/Pyro4/pyrolite.html[/url]
Maven仓库: [url]https://mvnrepository.com/artifact/net.razorvine/pyrolite/4.10[/url]

用Maven的话会自动下载依赖,如需要自己添加,需加依赖: serpent-1.12.jar

具体例子,github上有,我拷贝下:
先是服务端(Python):
注:
1. 比第一个例子中的稍微复杂,是因为使用了name-server(可自定义,比url好记、方便)。
2. 注解@Pyro4.expose表示要暴露的范围,若加在class前面说明里面所有的方法都可以被客户端所调用,若加在单个方法中,那么其它方法对外则不可见。
3. 加了security: hmac,这段代码只是起到安全作用,可不写,具体参见: [url]http://pythonhosted.org/Pyro4/security.html[/url]
4. 设了最简单的String参数,当然其它类型的也都可以支持。


import Pyro4

class GreetingMakerJava(object):
@Pyro4.expose
def get_fortune(self, name):
return "Hello, " + name;

daemon = Pyro4.core.Daemon() # make a Pyro daemond
daemon._pyroHmacKey = b'demokey'

ns = Pyro4.locateNS() # find the name server
uri = daemon.register(GreetingMakerJava) # register the greeting maker as a Pyro object
ns.register("example.greeting", uri) # register the object with a name in the name server

print("Ready.")
print(list(ns.list(prefix="example.").keys()))
daemon.requestLoop() # start the event loop of the server to wait for calls


Java客户端:

import net.razorvine.pyro.Config;
import net.razorvine.pyro.NameServerProxy;
import net.razorvine.pyro.PyroProxy;
public class TestPython {
public static void main(String[] args) throws Exception {
Config.METADATA = false; // Pyro4.56 have some bugs to get metadata.
NameServerProxy ns = NameServerProxy.locateNS(null);
PyroProxy remoteobject = new PyroProxy(ns.lookup("example.greeting"));
remoteobject.pyroHmacKey = "demokey".getBytes();
Object result = remoteobject.call("get_fortune", "allen");
String message = (String)result;
System.out.println("result message=" + message);
remoteobject.close();
ns.close();
}
}
// result message=Hello, allen


-------------------------------------------------------------------------
[b]使用过程中遇到的问题:[/b]

1. 在运行第1个例子的客户端,遇到错误: [color=red]ConnectionRefusedError: [Errno 61] Connection refused[/color]
需要打开python的name service:
>python3 -m Pyro4.naming
Not starting broadcast server for localhost.
NS running on localhost:9090 (127.0.0.1)
Warning: HMAC key not set. Anyone can connect to this server!
URI = PYRO:Pyro.NameServer@localhost:9090

参考: [url]http://stackoverflow.com/questions/34499331/pyro4-failed-to-locate-the-nameserver[/url]

2. 在运行第2个例子的客户端,遇到错误: [color=red]Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.HashSet[/color]

尝试解决,加上Config.METADATA = false;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值