提交 d3201707 编写于 作者: N Nicolas Hennion

Glances client/server is now fully RPC/XML compliant

上级 25e4686f
...@@ -35,7 +35,7 @@ import signal ...@@ -35,7 +35,7 @@ import signal
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
import gettext import gettext
import SocketServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
# International # International
#============== #==============
...@@ -2106,95 +2106,61 @@ class glancesCsv: ...@@ -2106,95 +2106,61 @@ class glancesCsv:
self.__cvsfile_fd.flush() self.__cvsfile_fd.flush()
class GlancesHandler(SocketServer.BaseRequestHandler): class GlancesHandler(SimpleXMLRPCRequestHandler):
""" """
!!! Main XMLRPC handler
!!! TODO : To be replaced by http://docs.python.org/2/library/simplexmlrpcserver.html
!!!
This class manages the TCP request
Return:
0: GET Command success
1: command unknown
2: INIT Command success
3: QUIT Command success
""" """
rpc_paths = ('/RPC2',)
def handle(self):
# Get command from the Glances client
self.datarecv = self.request.recv(1024)
#~ print "Receive the command %s from %s" % (format(self.datarecv), format(self.client_address[0]))
if (self.datarecv == "GET"):
# Send data to the Glances client
stats.update()
# JSONify and ZIP stats
# To be replaced when version 2.2.0 of the JSON will be available
#~ self.datasend = zlib.compress(json.dumps(stats.getAll(), namedtuple_as_object = True))
self.datasend = zlib.compress(json.dumps(stats.getAll()))
self.request.sendall(self.datasend)
return 0
elif (self.datarecv == "INIT"):
# Send Glances version to the client
self.datasend = __version__
self.request.sendall(self.datasend)
return 2
elif (self.datarecv == "QUIT"):
# Send Glances version to the client
self.datasend = "BYE"
self.request.sendall(self.datasend)
return 3
else:
print "Error: Unknown command received by Glances server"
return 1
class GlancesInstance():
"""
All the methods of this class are published as XML RPC methods
"""
def init(self):
return __version__
def get(self):
# Update and return all the stats
stats.update()
return json.dumps(stats.getAll())
class GlancesClient(): class GlancesServer():
""" """
This class creates and manages the TCP client This class creates and manages the TCP client
""" """
def __init__(self, server_address, server_port = 61209): def __init__(self, bind_address, bind_port = 61209, RequestHandler = GlancesHandler):
self.server_address = server_address self.server = SimpleXMLRPCServer((bind_address, bind_port),
self.server_port = server_port requestHandler=RequestHandler)
self.server.register_introspection_functions()
self.server.register_instance(GlancesInstance())
return return
def serve_forever(self):
self.server.serve_forever()
def server_close(self):
self.server.server_close()
def __sendandrecv__(self, command, jsonzip = True):
# Create a socket (SOCK_STREAM means a TCP socket)
SocketClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to server and send data
SocketClient.connect((self.server_address, self.server_port))
# Send command
SocketClient.sendall(command)
# Receive data from the server and shut down class GlancesClient():
buff_received = '' """
while True: This class creates and manages the TCP client
buff = SocketClient.recv(8192) """
if not buff: break
buff_received += buff
# Close the socket
SocketClient.close()
# Return the data sent by the server def __init__(self, server_address, server_port = 61209):
if jsonzip: self.client = xmlrpclib.ServerProxy('http://%s:%d' % (server_address, server_port))
# If asked: deJSONify and decompress return
return json.loads(zlib.decompress(buff_received))
else:
return buff_received
def client_init(self): def client_init(self):
if self.__sendandrecv__("INIT", jsonzip = False) != __version__: return __version__[:3] == self.client.init()[:3]
return 1
else:
return 0
def client_get(self): def client_get(self):
return self.__sendandrecv__("GET") return json.loads(self.client.get())
def client_quit(self):
return self.__sendandrecv__("QUIT", jsonzip = False)
# Global def # Global def
#=========== #===========
...@@ -2233,7 +2199,8 @@ def end(): ...@@ -2233,7 +2199,8 @@ def end():
else: else:
if client_tag: if client_tag:
# Stop the client loop # Stop the client loop
client.client_quit() #~ client.client_quit()
pass
# Stop the classical CLI loop # Stop the classical CLI loop
screen.end() screen.end()
...@@ -2251,6 +2218,7 @@ def signal_handler(signal, frame): ...@@ -2251,6 +2218,7 @@ def signal_handler(signal, frame):
# Main # Main
#===== #=====
if __name__ == "__main__": if __name__ == "__main__":
# Glances - Init stuff # Glances - Init stuff
...@@ -2494,27 +2462,27 @@ if __name__ == "__main__": ...@@ -2494,27 +2462,27 @@ if __name__ == "__main__":
# Init Glances depending of the mode (standalone, client, server) # Init Glances depending of the mode (standalone, client, server)
if server_tag: if server_tag:
from SimpleXMLRPCServer import SimpleXMLRPCServer
import json import json
import zlib
import collections import collections
# Init the server # Init the server
print(_("Glances is listenning on %s:%s") % (bind_ip, server_port)) print(_("Glances is listenning on %s:%s") % (bind_ip, server_port))
server = SocketServer.TCPServer((bind_ip, server_port), GlancesHandler) server = GlancesServer(bind_ip, server_port, GlancesHandler)
# Init stats # Init stats
stats = glancesStats(server_tag = True) stats = glancesStats(server_tag = True)
elif client_tag: elif client_tag:
import socket import xmlrpclib
import json import json
import zlib
import collections import collections
# Init the client (displaying server stat in the CLI) # Init the client (displaying server stat in the CLI)
client = GlancesClient(server_ip, server_port) client = GlancesClient(server_ip, server_port)
if client.client_init() != 0: # Test if client and server are in the same major version
if not client.client_init():
print(_("Error: The server version is not compatible")) print(_("Error: The server version is not compatible"))
sys.exit(2) sys.exit(2)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册