code: def _rpc(self, method, *args):
          
          with self._lock:
              apiid = next(self._counter)
              data = {'id': apiid, 'method': method, 'params': args}
              request = json.dumps(data)
              self._client_send(request)
              response = self._client_receive()
          if not response:
              raise ProtocolError(self._ad,
                                  ProtocolError.NO_RESPONSE_FROM_SERVER)
          result = json.loads(str(response, encoding='utf8'))
          if result['error']:
              raise ApiError(self._ad, result['error'])
          if result['id'] != apiid:
              raise ProtocolError(self._ad, ProtocolError.MISMATCHED_API_ID)
          if result.get('callback') is not None:
              if self._event_client is None:
                  self._event_client = self._start_event_client()
              return callback_handler.CallbackHandler(
                  callback_id=result['callback'],
                  event_client=self._event_client,
                  ret_value=result['result'],
                  method_name=method,
                  ad=self._ad)
          return result['result']
docs: Sends an rpc to the app.
  
          Args:
              method: str, The name of the method to execute.
              args: any, The args of the method.
  
          Returns:
              The result of the rpc.
  
          Raises:
              ProtocolError: Something went wrong with the protocol.
              ApiError: The rpc went through, however executed with errors.