Newer
Older
#!/usr/bin/env python
#coding=utf8
import ssl
import select
import socket
from sjrpc.core import RpcConnection, ConnectionManager
class SimpleRpcClient(ConnectionManager):
'''
Create a new simple RPC client.
:param connect: the :class:`RpcConnection` object to bind the client manager
:param default_handler: the default handler to bind to the client connection
:param on_disconnect: method on the handler to call when the client
disconnects.
'''
def __init__(self, connection, default_handler=None, on_disconnect=None):
super(SimpleRpcClient, self).__init__()
self._on_disconnect = on_disconnect
self._connection = connection
self._connection.set_handler(default_handler)
def from_addr(cls, addr, port, enable_ssl=False, cert=None, timeout=30.0,
default_handler=None, on_disconnect=None):
'''
Construct the instance of :class:`SimpleRpcClient` without providing
the :class:`RpcConnection` object. The :class:`RpcConnection` is
automatically created and passed to the standard constructor before to
return the new instance.
:param addr: the target ip address
:param port: the target port
:param ssl: enable SSL
:param cert: is SSL is enabled, profile the filename of certificate to
check. If None, don't check certificate.
:param default_handler: the default handler to bind to the
client connection
:param on_disconnect: method on the handler to call when the client
disconnects.
'''
connection = RpcConnection.from_addr(addr, port, None, timeout=timeout,
client = cls(connection, default_handler=default_handler,
on_disconnect=on_disconnect)
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
connection._manager = client
return client
@classmethod
def from_sock(cls, sock, default_handler=None, on_disconnect=None):
'''
Construct the instance of :class:`SimpleRpcClient` without providing
the :class:`RpcConnection` object. The :class:`RpcConnection` is
automatically created and passed to the standard constructor before to
return the new instance
:param sock: the socket object to wrap with :class:`RpcConnection`
object.
:param default_handler: the default handler to bind to the
client connection
:param on_disconnect: method on the handler to call when the client
disconnects.
'''
connection = RpcConnection(sock, None)
client = cls(connection, default_handler, on_disconnect)
connection._manager = client
return client
def shutdown(self):
super(SimpleRpcClient, self).shutdown()
self._connection.shutdown(self._on_disconnect)
def handle_event(self, fd, event):
if event & select.EPOLLIN:
# Data are ready to be readed on socket
try:
self._connection.receive()
except socket.error as err:
logging.error('Socket error while receiving from the client '
'fd/%s: %s' % (fd, err))
self.shutdown()
if event & select.EPOLLOUT:
# Data are ready to be written on socket
try:
self._connection.send()
except socket.error as err:
logging.error('Socket error while sending to the client '
'fd/%s: %s' % (fd, err))
self.shutdown() #TODO
def all_connections(self):
return set((self._connection,))
def call(self, *args, **kwargs):
return self._connection.call(*args, **kwargs)