Loading...
Searching...
No Matches
net_channel.cpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
21
22#include <glog/logging.h>
23
26
27namespace resdb {
28
29NetChannel::NetChannel(const std::string& ip, int port) : ip_(ip), port_(port) {
30 socket_ = std::make_unique<TcpSocket>();
31 socket_->SetSendTimeout(300);
32 socket_->SetRecvTimeout(read_timeouts_);
33}
34
35void NetChannel::SetRecvTimeout(int microseconds) {
36 read_timeouts_ = microseconds;
37 socket_->SetRecvTimeout(read_timeouts_);
38}
39
40void NetChannel::SetAsyncSend(bool is_async_send) {
41 is_async_send_ = is_async_send;
42}
43
44NetChannel::NetChannel(std::unique_ptr<Socket> socket, bool connected) {
45 SetSocket(std::move(socket));
46 connected_ = connected;
47}
48
49void NetChannel::Close() { socket_->Close(); }
50
54
55void NetChannel::SetSocket(std::unique_ptr<Socket> socket) {
56 socket_ = std::move(socket);
57}
58
59void NetChannel::SetDestReplicaInfo(const ReplicaInfo& replica) {
60 ip_ = replica.ip();
61 port_ = replica.port();
62}
63
64void NetChannel::IsLongConnection(bool long_connect_tion) {
65 long_connect_tion_ = long_connect_tion;
66}
67
69 socket_->ReInit();
70 socket_->SetAsync(is_async_send_);
71 return socket_->Connect(ip_, port_);
72}
73
74int NetChannel::SendDataInternal(const std::string& data) {
75 return socket_->Send(data);
76}
77
78// Connect to the server if not connected and send data.
79int NetChannel::SendFromKeepAlive(const std::string& data) {
80 for (int i = 0; i < max_retry_time_; ++i) {
81 if (!long_connecting_) {
82 if (Connect() == 0) {
83 long_connecting_ = true;
84 }
85 if (!long_connecting_) {
86 LOG(ERROR) << "connect fail:" << ip_ << " port:" << port_;
87 continue;
88 }
89 }
90 int ret = SendDataInternal(data);
91 if (ret >= 0) {
92 return ret;
93 }
94 long_connecting_ = false;
95 }
96 return -1;
97}
98
99int NetChannel::Send(const std::string& data) {
100 if (long_connect_tion_) {
101 return SendFromKeepAlive(data);
102 }
103 for (int i = 0; i < max_retry_time_; ++i) {
104 if (!connected_) {
105 if (Connect()) {
106 LOG(ERROR) << "connect fail:" << ip_ << " port:" << port_;
107 continue;
108 }
109 }
110 int ret = SendDataInternal(data);
111 if (ret >= 0) {
112 return ret;
113 } else if (ret == -1) {
114 LOG(ERROR) << "send data fail:" << ip_ << " port:" << port_;
115 }
116 }
117 return -1;
118}
119
120// Receive data from the server.
121int NetChannel::Recv(std::string* data) {
122 std::unique_ptr<DataInfo> resp = std::make_unique<DataInfo>();
123 int ret = socket_->Recv(&resp->buff, &resp->data_len);
124 if (ret > 0) {
125 *data = std::string((char*)resp->buff, resp->data_len);
126 }
127 return ret;
128}
129
130// Sign the message if verifier has been provied and send the message to the
131// server.
133 const google::protobuf::Message& message, SignatureVerifier* verifier) {
134 ResDBMessage sig_message;
135 if (!message.SerializeToString(sig_message.mutable_data())) {
136 return "";
137 }
138
139 if (verifier != nullptr) {
140 auto signature_or = verifier->SignMessage(sig_message.data());
141 if (!signature_or.ok()) {
142 LOG(ERROR) << "Sign message fail";
143 return "";
144 }
145 sig_message.mutable_signature()->Swap(&(*signature_or));
146 } else {
147 // LOG(ERROR) << " no verifier";
148 }
149
150 std::string message_str;
151 if (!sig_message.SerializeToString(&message_str)) {
152 return "";
153 }
154 return message_str;
155}
156
157int NetChannel::SendRawMessageData(const std::string& message_str) {
158 return Send(message_str);
159}
160
161int NetChannel::RecvRawMessageData(std::string* message_str) {
162 return Recv(message_str);
163}
164
165int NetChannel::SendRawMessage(const google::protobuf::Message& message) {
166 ResDBMessage sig_message;
167 if (!message.SerializeToString(sig_message.mutable_data())) {
168 return -1;
169 }
170
171 if (verifier_ != nullptr) {
172 auto signature_or = verifier_->SignMessage(sig_message.data());
173 if (!signature_or.ok()) {
174 LOG(ERROR) << "Sign message fail";
175 return -1;
176 }
177 sig_message.mutable_signature()->Swap(&(*signature_or));
178 }
179 std::string message_str;
180 if (!sig_message.SerializeToString(&message_str)) {
181 return -1;
182 }
183 return Send(message_str);
184}
185
186int NetChannel::RecvRawMessageStr(std::string* message) {
187 std::string recv_str;
188 int ret = Recv(&recv_str);
189 if (ret <= 0) {
190 return ret;
191 }
192 ResDBMessage sig_message;
193 if (!sig_message.ParseFromString(recv_str)) {
194 LOG(ERROR) << "parse to sig fail";
195 return -1;
196 }
197 *message = sig_message.data();
198 return 0;
199}
200
201int NetChannel::RecvRawMessage(google::protobuf::Message* message) {
202 std::string resp_data;
203 int ret = Recv(&resp_data);
204 if (ret < 0) {
205 LOG(ERROR) << "recv fail:" << ret;
206 return -1;
207 }
208 ResDBMessage sig_message;
209 if (!sig_message.ParseFromString(resp_data)) {
210 LOG(ERROR) << "parse sig msg fail";
211 return -1;
212 }
213 if (!message->ParseFromString(sig_message.data())) {
214 LOG(ERROR) << "parse response msg fail";
215 return -1;
216 }
217 return 0;
218}
219
220int NetChannel::SendRequest(const google::protobuf::Message& message,
221 Request::Type type, bool need_response) {
222 Request request;
223 request.set_type(type);
224 request.set_need_response(need_response);
225 if (!message.SerializeToString(request.mutable_data())) {
226 return -1;
227 }
228 return SendRawMessage(request);
229}
230
231} // namespace resdb
std::string data
virtual int SendRawMessage(const google::protobuf::Message &message)
virtual int RecvRawMessageData(std::string *message_str)
std::string ip_
void SetRecvTimeout(int microseconds)
virtual int RecvRawMessageStr(std::string *message)
SignatureVerifier * verifier_
Definition net_channel.h:96
virtual int SendRawMessageData(const std::string &message_str)
std::unique_ptr< Socket > socket_
Definition net_channel.h:98
virtual int RecvRawMessage(google::protobuf::Message *message)
virtual int SendRequest(const google::protobuf::Message &message, Request::Type cmd, bool need_response=false)
void SetSocket(std::unique_ptr< Socket > socket)
int SendFromKeepAlive(const std::string &data)
void SetDestReplicaInfo(const ReplicaInfo &replica)
void SetAsyncSend(bool is_async_send)
int Recv(std::string *data)
void SetSignatureVerifier(SignatureVerifier *verifier)
static std::string GetRawMessageString(const google::protobuf::Message &message, SignatureVerifier *verifier=nullptr)
NetChannel(const std::string &ip, int port)
int SendDataInternal(const std::string &data)
int Send(const std::string &data)
void IsLongConnection(bool long_connect_tion)
virtual absl::StatusOr< SignatureInfo > SignMessage(const std::string &message)