def call(self, args=None, kwargs=None, node=None, send_timeout=1000, recv_timeout=5000, zmq_ctx=None):
        """
        Calls a service on a node with req as arguments. if node is None, a node is chosen by zmq.
        if zmq_ctx is passed, it will use the existing context
        Uses a REQ socket. Ref : http://api.zeromq.org/2-1:zmq-socket
        :param node : the node name

        """

        context = zmq_ctx or zmq.Context()
        assert isinstance(context, zmq.Context)

        args = args or ()
        assert isinstance(args, tuple)
        kwargs = kwargs or {}
        assert isinstance(kwargs, dict)

        socket = context.socket(zmq.REQ)

        # connect to all addresses ( optionally matching node name )
        for n, a in [(n, a) for (n, a) in self.providers if (not node or n == node)]:
            socket.connect(a)

        # build message
        fullreq = ServiceRequest(service=self.name, args=pickle.dumps(args), kwargs=pickle.dumps(kwargs))

        poller = zmq.Poller()
        poller.register(socket)  # POLLIN for recv, POLLOUT for send

        evts = dict(poller.poll(send_timeout))
        if socket in evts and evts[socket] == zmq.POLLOUT:
            socket.send(fullreq.serialize())
            # TODO : find a way to get rid fo these timeouts when debugging
            # TODO : when timeout Exception should occur ( not returning None )
            evts = dict(poller.poll(recv_timeout))  # blocking until answer
            if socket in evts and evts[socket] == zmq.POLLIN:
                resp = socket.recv()
                fullresp = ServiceResponse_dictparse(resp)

                if fullresp.has_field('response'):
                    return pickle.loads(fullresp.response)
                elif fullresp.has_field('exception'):
                    svcexc = fullresp.exception  # This has already been parsed by ServiceResponse_dictparse
                    tb = pickle.loads(svcexc.traceback)
                    if Traceback and isinstance(tb, Traceback):
                        reraise(pickle.loads(svcexc.exc_type), pickle.loads(svcexc.exc_value), tb.as_traceback())
                    else:  # traceback not usable
                        reraise(pickle.loads(svcexc.exc_type), pickle.loads(svcexc.exc_value), None)
                else:
                    raise UnknownResponseTypeException("Unknown Response Type {0}".format(type(fullresp)))
            else:
                raise ServiceCallTimeout("Did not receive response through ZMQ socket.")
        else:
            raise ServiceCallTimeout("Can not send request through ZMQ socket.")
Calls a service on a node with req as arguments. if node is None, a node is chosen by zmq.
        if zmq_ctx is passed, it will use the existing context
        Uses a REQ socket. Ref : http://api.zeromq.org/2-1:zmq-socket
        :param node : the node name