rpc/example/client.cpp (106 lines of code) (raw):
/*
Copyright 2022 The Photon Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "client.h"
#include <photon/common/alog-stdstring.h>
#include <photon/common/alog.h>
#include <photon/common/iovector.h>
#include <photon/net/socket.h>
#include <ctime>
int64_t ExampleClient::RPCHeartbeat(photon::net::EndPoint ep) {
Heartbeat::Request req;
req.now = photon::now;
Heartbeat::Response resp;
int ret = 0;
auto stub = pool->get_stub(ep, false);
if (!stub) return -1;
DEFER(pool->put_stub(ep, ret < 0));
ret = stub->call<Heartbeat>(req, resp);
if (ret < 0) return -errno;
return resp.now;
}
std::string ExampleClient::RPCEcho(photon::net::EndPoint ep,
const std::string& str) {
Echo::Request req;
req.str.assign(str);
Echo::Response resp;
// string or variable length fields should pre-set buffer
char tmpbuf[4096];
resp.str = {tmpbuf, 4096};
int ret;
auto stub = pool->get_stub(ep, false);
if (!stub) return {};
DEFER(pool->put_stub(ep, ret < 0));
ret = stub->call<Echo>(req, resp);
if (ret < 0) return {};
std::string s(resp.str.c_str());
return s;
}
void ExampleClient::RPCEchoPerf(photon::net::EndPoint ep, void *req_buf, void *resp_buf, size_t buf_size) {
Echo::Request req;
req.str.assign(req_buf, buf_size);
Echo::Response resp;
resp.str.assign(resp_buf, buf_size);
int ret = -1;
auto stub = pool->get_stub(ep, false);
if (!stub) exit(1);
DEFER(pool->put_stub(ep, ret < 0));
ret = stub->call<Echo>(req, resp);
if (ret < 0) exit(1);
}
ssize_t ExampleClient::RPCRead(photon::net::EndPoint ep, const std::string& fn,
const struct iovec* iovec, int iovcnt) {
ReadBuffer::Request req;
req.fn.assign(fn);
ReadBuffer::Response resp;
resp.buf.assign(iovec, iovcnt);
int ret = 0;
auto stub = pool->get_stub(ep, false);
if (!stub) return -1;
DEFER(pool->put_stub(ep, ret < 0));
ret = stub->call<ReadBuffer>(req, resp);
if (ret < 0) return ret;
return resp.ret;
}
ssize_t ExampleClient::RPCWrite(photon::net::EndPoint ep, const std::string& fn,
struct iovec* iovec, int iovcnt) {
WriteBuffer::Request req;
req.fn.assign(fn);
req.buf.assign(iovec, iovcnt);
WriteBuffer::Response resp;
int ret = 0;
auto stub = pool->get_stub(ep, false);
if (!stub) return -1;
DEFER(pool->put_stub(ep, ret < 0));
ret = stub->call<WriteBuffer>(req, resp);
if (ret < 0) return ret;
return resp.ret;
}
void ExampleClient::RPCTestrun(photon::net::EndPoint ep) {
Testrun::Request req;
// prepare some data
int iarr[] = {1, 2, 3, 4};
// sample of
char buf1[] = "some";
char buf2[] = "buf";
char buf3[] = "content";
IOVector iov;
iov.push_back(buf1, 4);
iov.push_back(buf2, 3);
iov.push_back(buf3, 7);
// set up request
req.someuint = 2233U;
req.someint64 = 4455LL;
req.somestruct = Testrun::SomePODStruct{.foo = true, .bar = 32767};
req.intarray.assign(iarr, 4);
req.somestr.assign("Hello");
req.buf.assign(iov.iovec(), iov.iovcnt());
// make room for response
Testrun::Response resp;
// iovector should pre_allocated
IOVector riov;
riov.push_back(1024);
resp.buf.assign(riov.iovec(), riov.iovcnt());
int ret = 0;
auto stub = pool->get_stub(ep, false);
if (!stub) return;
DEFER(pool->put_stub(ep, ret < 0));
// Single step call
ret = stub->call<Testrun>(req, resp);
// ret < 0 means RPC failed on send or receive
if (ret < 0) {
LOG_INFO("RPC fail");
} else {
LOG_INFO("RPC succ: ", VALUE(resp.len),
VALUE((char*)riov.begin()->iov_base));
}
}