Client

To interact with other microservice instances and to call their remote methods, we will create a separate struct, because it's more convenient than using the JSON-RPC Cilent directly. But in any case, we use this type internally in our struct:

struct Remote {
client: Client,
}

We will use the Remote struct to make calls to remote services. To create the struct, we will use the following constructor:

impl Remote {
fn new(addr: SocketAddr) -> Self {
let url = format!("http://{}", addr);
let client = Client::new(url, None, None);
Self {
client
}
}
}

The Client struct expects the String URL as a parameter, but we will use SocketAddr to create a URL.

Also, we need a generic function that will use the Client instance to call remote methods. Add the call_method method to the implementation of the Remote struct:

fn call_method<T>(&self, meth: &str, args: &[Value]) -> Result<T, ClientError>
where
T: for <'de> Deserialize<'de>,
{
let request = self.client.build_request(meth, args);
self.client.send_request(&request).and_then(|res| res.into_result::<T>())
}

The calling of the JSON-RPC method using the JSON-RPC crate is simple. Use the build_request method of the Client instance to create a Request and send it using the send_request method of the same Client. There is a method called do_rpc that does this in a single call. We will use a more verbose approach to show that you can predefine requests and use them to speed up the preparation for calling. Also, it's more pleasant to use business-oriented struct methods instead of a raw Client. We isolate an implementation using a wrapper that hides the details of RPC calls. What if you decide to change to another protocol, such as gRPC?

Add special methods to the Remote struct implementation to make calls using the call_method method. First, we need the start_roll_call function:

fn start_roll_call(&self) -> Result<bool, ClientError> {
self.call_method(START_ROLL_CALL, &[])
}

It won't pass any parameters with a call, but it expects the bool type of the result. We used a constant for the remote method's name.

Add the mark_itself method to the Remote struct:

fn mark_itself(&self) -> Result<bool, ClientError> {
self.call_method("mark_itself", &[])
}

It doesn't send any parameters either and returns the bool value.

Now we can add a worker to separate outgoing method calls from incoming calls.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.73.127