Remote Python Call (RPyC) 是一个 Python 的库用来实现 RPC 和分布式计算的工具。支持同步和异步操作、回调和远程服务以及透明的对象代理
功能
透明 -访问远程对象,如果它们是本地现有的代码可以无缝地与本地或远程对象。
对称 -协议本身是完全对称的,这意味着可以为客户端和服务器请求。除其他外,这使得服务器调用客户端回调。
同步和异步操作
平台无关 - 32/64位,小/大端的Windows / Linux / Solaris / Mac上的... 访问对象在不同的架构。
低开销 - RpyC需要的所有功能于一身的做法,采用紧凑的二进制协议,无需复杂的设置(域名服务器的HTTP URL映射等)
安全 -采用了能力为基础 的安全模型
集成的TLS / SSL, SSH的和inetd的。
###本文所解决问题:
使用RPyC时,若在Host(主机)端print,则只是在Host打印。如何能让Host的print直接打印到Client上呢?
###直接上代码
首先是客户端的:
import sys
import rpyc
conn = rpyc.connect("localhost", port=18861, config={"allow_public_attrs":True})
conn.root.redirect(sys.stdout)
conn.root.git_clone()
conn.close()
服务端的:
import rpyc
import os
import sys
import subprocess
class MyService(rpyc.Service):
def exposed_redirect(self, stdout):
sys.stdout = stdout
def exposed_restore(self):
sys.stdout = sys.__stdout__
def exposed_git_clone(self):
p = subprocess.Popen(["git", 'clone', 'git@github.com:ejoy/ejoy2d.git', '--progress'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
nextline = p.stderr.readline()
if nextline == '' and p.poll() != None:
break
print nextline
if __name__ == "__main__":
from rpyc.utils.server import ThreadedServer
t = ThreadedServer(MyService, port = 18861)
t.start()
运行后,你会发现,print nextline这条命令是打印到客户端上去了。
这里还有一个小地方值得注意的是:
git clone/pull/push 这类操作,事实上是不会向stdout/stderr里面写内容的(除非发送错误)。但是如果加上了--progress,那么就会把进度往stderr里面写。这样,我们的subprocess的stderr才能被读到。