Package: as-rpc
as_rpcas_rpcis a python package for Remote Procedure Call (RPC) based-onAsynchronous IOandSocket.It supports bidirectional calls, and it has very high efficiency.Quick StartTo installas-rpc, run the commandpip install as-rpcLet's run the program first, and then some more details on how to useas-rpcwill be given.Suppose we have two files, one for server and the other for client.Server Example (see alsotest_server.py)fromas_rpcimportAioRpcServer,rpcimportasyncioserver=AioRpcServer()@rpc(server,"test")defprint_test(content):print("hello world!",content)returnstr(content)@rpc(server,0)deftest0(*args):return1@rpc(server,1)deftest1():s="this is test1."print(s)returns@rpc(server,2)asyncdeftest2():s="this is test2."print(s)returns@rpc(server,'Foo')classFoo:@rpc(server,3)asyncdeftest3(self):s="this is test3."print(s)returns@rpc(server,4)deftest4(self):s="this is test4."print(s)returns@rpc(server,"call_client")asyncdefcall_client(client_id):print("call client")msg=awaitserver.async_call_func(client_id,"test","msg from server")print(msg)server.run()Client Example (see alsotest_client.py)importasynciofromas_rpcimportAioRpcClient,RpcServerObject,rpcfromtimeimporttimedefcallback(data):print(data)client=AioRpcClient()client.init()defmain():print('main')client.call_func(1,callback)client.call_func("test",callback,RpcServerObject(client.id))asyncdefmain2():s=awaitclient.async_call_func(1)print('async',s)asyncdefmain3():foo=awaitclient.async_instantiate('Foo')print(foo)print(awaitclient.async_call_async_method(foo,3))print(awaitclient.async_call_method(foo,4))@rpc(client,"test")deftest(msg):print(msg)return"return from client"loop=asyncio.get_event_loop()loop.call_soon(main)loop.run_until_complete(main2())loop.run_until_complete(main3())loop.run_until_complete(client.async_call_async_func("call_client",client.id))In one terminal, run the commandpython test_server.pyIn another terminal, run the commandpython test_client.pyYou will see the outputs from the serverthis is test1.
hello world! None
this is test1.
this is test3.
this is test4.
call client
return from clientand the outputs from the clientmain
('this is test1.', None)
('None', None)
async this is test1.
-8991251603859186137
this is test3.
this is test4.
msg from serverIn the client, the program calls some functions in the server, gets the return values, and prints them.Create and Run a Server/ClientTo create a server, first import related objectsfromas_rpcimportAioRpcServer,rpcand then instantiate a server byserver=AioRpcServer()To run the server, you can either callserver.init()and then start the event-loop ofasyncioserver.init()loop=asyncio.get_event_loop()loop.run_forever()or just callserver.run()which packs the code aboveserver.run()To create a client, first import related objectsfromas_rpcimportAioRpcClient,rpcand then instantiate a client byclient=AioRpcClient()To run the client, callclient.init()and then start the event-loop ofasyncioclient.init()loop=asyncio.get_event_loop()loop.run_forever()Register FunctionsYou can register a function or async function by adding adecoratoron a function, for example@rpc(server,0)deftest0(*args):return0@rpc(server,"test1")asyncdeftest1(*args):return1In@rpc(server, name), the first parameter is the server instance, while the second parameter is the name denoting the corresponding function. Client can call this function by the name defined here. For example, in clients=awaitclient.async_call_async_func("test1")There are four types of calling a function:call_func(),async_call_func(),call_async_func(), andasync_call_async_func(). The meaning of them will be illustrated later (see the section "Call Functions").In client programe, functions can also be registered in the same way.@rpc(client,"test")deftest(msg):print(msg)return"return from client"Call FunctionsFor a client, there are four types of calling a function:call_func(name_func, callback, *args): call a normal function directly in the remote. The first parameter is the function name in the remote (server or client); the second parametercallbackis a function which would be called after the result from the remote is returned. It could beNoneif the returned value is not concerned. The subsequentargsis a list of arguments passed to the remote.async_call_func(name_func, *args): call a normal function asynchronously in the remote. You can useawait async_call_func(...)to get the returned value, so there is no need to claim the callback function.call_async_func(name_func, callback, *args): call an async function directly in the remote. The function in the remote is asynchronous, defined with keywordasync. The parameters are the same ascall_func().async_call_async_func(name_func, *args): call an async function asynchronously in the remote. The parameters are the same ascall_async_func().For a server, there are also four types of calling a function, with the same names as the above. The difference is that there is an additional parameter in the first postion of each of the four, i.e.,client_id.call_func(client_id, name_func, callback, *args),async_call_func(client_id, name_func, *args),call_async_func(client_id, name_func, callback, *args),async_call_async_func(client_id, name_func, *args).The parameterclient_iddetermines which client to call.An example of calling a function by server is@rpc(server,"call_client")asyncdefcall_client(client_id):print("call client")msg=awaitserver.async_call_func(client_id,"test","msg from server")print(msg)All the clients' ids are avaible throughserver.clients.keys().Instantiate Classes and Call MethodsFor a client, you can create an instance of class in the remote byinstantiate(<Remote-Class-Marker>)orasync_instantiate(<Remote-Class-Marker>). The returned value is the handler of the remote instance.To call a method of it, you can use the fourcall_method(self, name_self, name_method, callback, *args),async_call_method(self, name_self, name_method, *args),call_async_method(self, name_self, name_method, callback, *args),async_call_async_method(self, name_self, name_method, *args).The difference among the four types is similar to the previous.An example to instantiate a class and to call methods isfoo=awaitclient.async_instantiate('Foo')print(foo)print(awaitclient.async_call_async_method(foo,3))print(awaitclient.async_call_method(foo,4))For a server, you can do similar things, except that you need to pass a parameterclient_idfor each calling.That's all about the usage of as-rpc. You can raise issues in the github repo if you have questions, want to report bugs, or need more features.BenchmarkFrameworkSpeed (req/s)zero (v0.4.1)2173as-rpc (this repo)10244