在python中运行有状态的RPC服务器

时间:2015-03-20 18:07:28

标签: python-2.7 rpc stateful

我需要在python 2.7.9中运行一个rpc服务器,它接受一个应该永远运行的对象并一致地更新它的状态。下面是伪代码:

class State(object):
    def __init__(self):
        self.count = 0

    def update_count(self):
        self.count += 1

和一个将侦听端口的RPC服务器

class Server(object):
    def __init__(self, state):
        self.state = state

    def start_state_service(self):
        while True:
            self.state.update_count()
            time.sleep(2)

    def start_rpc_server(self):
        start_to_listen(localhost, 9000)

    def get_count(self):
        return self.state.count


if __name__ == '__main__':
    state = State()
    srv = Server(state)
    srv.start_state_service()
    srv.start_rpc_server()

客户端看起来像那样:

class Client(object):
    def get_count(self):
        c = connect_to_server(localhost, 9000) 
        c.get_count()      

你能告诉我你将如何实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。我的服务将是一个从多处理继承的对象,以便它可以在后台启动。然后我创建一个SimpleXMLRPCServer,它将根据请求进行监听。除了在pickle文件中放置对象的更新之外,我发现无法提供对象的状态(即计数)。

#!/usr/bin/env python
# encoding: utf-8


"""
Create an XML-RPC Server that register several serices that run
in paralel in the background but can be invoked to know their state
"""


import multiprocessing
import time
import pickle
from SimpleXMLRPCServer import SimpleXMLRPCServer


class Service(multiprocessing.Process):
    """A service the increment a variable. """

    def __init__(self):
        """TODO: to be defined1. """
        multiprocessing.Process.__init__(self)
        self.count = 0

    def update_count(self):
        """ Update the counter """
        self.count += 1
        database = open('datafile.pkl', 'wb')
        pickle.dump(self.count, database)
        database.close()

    def run(self):
        """ Overloaded function provided by multiprocessing.Process.
            Called upon start() signal """
        end_time = time.time() + 120
        while time.time() < end_time:
            self.update_count()
            print self.count
            time.sleep(2)


def main():
    """ Main function """
    srv = Service()
    srv.start()

    def get_count():
        """Get state for the object"""
        database = open('datafile.pkl', 'rb')
        data = pickle.load(database)
        return data

    swift_srv = SimpleXMLRPCServer(('localhost', 9000), logRequests=True,
                                   allow_none=True)
    swift_srv.register_function(get_count)

    try:
        print 'Use Control-C to exit'
        swift_srv.serve_forever()
    except KeyboardInterrupt:
        print 'Exiting'

if __name__ == "__main__":
     main()

然后客户端非常简单:

#!/usr/bin/env python
# encoding: utf-8


import xmlrpclib

proxy = xmlrpclib.ServerProxy('http://localhost:9000', allow_none=True)
print proxy.get_count()