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才能被讀到。