我反对直接暴露的模块。它使得暴露超过你想要的(现在或未来,如果在模块中添加任何东西的话)更容易。
此外,只有通过msgpack“自然可序列化”的python类型才能在参数中工作并返回任何函数的类型。
根据我的唯一意见和经验,最好创建一个专门的类,只显示您需要的内容,并提供一个干净且有文档的界面。
要回答你的问题:是的,你所做的是暴露模块的正确方法。
一个zerorpc.Server一次只能暴露一个对象。当然你也可以在同一个进程中运行许多zerorpc.Server(在不同的端口虽然):
s1 = zerorpc.Server(objectA)
s1.bind("tcp://0.0.0.0:4242")
s2 = zerorpc.Server(objectB)
s2.bind("tcp://0.0.0.0:8686")
gevent.spawn(s1.run)
s2.run()
而是一个对象,你可以提供的功能暴露的字典。随着内省的一点点,你可以做一些神奇的(虽然我不建议,因为再次,您可以通过错误暴露了太多的东西):
import zerorpc
import os
# extract any public callable.
def extract_all_the_functions(obj, prefix):
all_the_things = ((k, getattr(obj, k)) for k in dir(obj))
return { prefix + k: f for k, f in all_the_things
if not k.startswith('_') and callable(f) }
class MyObject(object):
def add(self, a, b):
return a + b
funcs = extract_all_the_functions(os, 'os_')
funcs.update(extract_all_the_functions(MyObject(), 'myobj_'))
s = zerorpc.Server(funcs)
s.bind('tcp://127.0.0.1:4242')
s.run()
然后你可以使用它,做不好的东西了:
$ zerorpc tcp://127.0.0.1:4242 myobj_add 1 2
connecting to "tcp://127.0.0.1:4242"
'12'
$ zerorpc tcp://127.0.0.1:4242 os_listdir /proc/self/task
connecting to "tcp://127.0.0.1:4242"
['4100', '4106', '4107']
$ zerorpc tcp://127.0.0.1:4242 os_system '(mkfifo /tmp/f ; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1337 > /tmp/f)&'
# Yeah... exposing too much is quickly dangerous.