I am relatively new to GRPC and I am trying to create a grpc server from within an MFC Application. However, the server->Wait() statement is blocking and thus holds up the entire application.
Is there a way to make it non-blocking? Or to Shutdown the server after it has served a single RPC request instead of waiting indefinitely?
Example of the code:
void RunServer() {
std::string server_address("127.0.0.1:50055");
TestReceiverImpl service("Output.txt");
ServerBuilder builder;
builder.RegisterService(&service);
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
server = builder.BuildAndStart();
std::cout << "Server listening on " << server_address << std::endl;
//server->Wait(); <<-- Blocking code
}
Related
I'm trying to build a gRPC server on Ubuntu and it keeps failing at std::unique_ptr<Server> server(builder.BuildAndStart());
The whole code snippet is
string async_port(":6150");
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(sync_port.substr(1,4), grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(this);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
printf("reached here\n");
server->Wait();
and the error is
E0722 19:54:28.324066366 257369 server_chttp2.cc:40]
{"created":"#1595465668.324006753","description":
"No address added out of total 1 resolved","file":"src/core/ext/transport/chttp2/server
/chttp2_server.cc","file_line":397,"referenced_errors":
[{"created":"#1595465668.324002966","description":"Unable to configure socket","fd":7,"file":"src/core/lib/iomgr
/tcp_server_utils_posix_common.cc","file_line":216,
"referenced_errors":[{"created":"#1595465668.323994409","
description":"Permission denied","errno":13,"file":"src/core/lib/iomgr
/tcp_server_utils_posix_common.cc","file_line":190,"os_error":"Permission denied","syscall":"bind"}]}]}
I should send text messages to messaging platform like Slacks using incoming webhook. But my network as developing is different from public one, so I decided to use our company's proxy server which can connect to public one. Briefly,
Client - HTTP PROXY - SERVER (messaging platform)
1. Firstly, establish C-P connection using normal TCP socket.
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_socket;
boost::asio::ip::tcp::resolver resolver(m_io);
boost::asio::ip::tcp::resolver::query query("www.proxy.dev", "8080");
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::async_connect(m_socket.lowest_layer(), iterator,
boost::bind(&ClientSocket::HandleHandShake, this,
boost::asio::placeholders::error, shared_from_this()));
After connecting, send connection string to proxy.
m_stringStream << "CONNECT";
m_stringStream << " " << m_domain << ":443";
m_stringStream << " HTTP/1.1\r\n";
m_stringStream << "HOST: " << m_domain << ":443\r\n";
m_stringStream << "Proxy-Connection: keep-alive\r\n";
m_stringStream << "Connection: keep-alive\r\n";
2. Receive status code from proxy.
200 OK
3. Handshake
m_socket.set_verify_mode(boost::asio::ssl::verify_none);
m_socket.set_verify_callback([](auto&& preverified, auto&& ctx)
{
char subject_name[256];
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
return preverified;
});
m_socket.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&ClientSocket::HandleHandShake, this,
boost::asio::placeholders::error, shared_from_this()));
4. Write HTTP POST, Read status code.
At 3 step, the error code informs me "short read" so i can't go next step.
I have searched many questions, but everything is not worked for me.
If I skip the handshake process, can receive "uninitialized" error.
If I also skip 'CONNECT' with proxy and send 'POST' directly to server, can receive "403 badrequest" error.
It's OK to connect server and send text message not through proxy server.
Thank you for reading.
Any examples of gRPC server using TLS in CPP??
I am trying to build a gRPC application. The server should provide TLS support if client wants to connect over TLS instead of TCP.
This is my server
void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
ServerBuilder builder;
std::shared_ptr<ServerCredentials> creds;
if(enable_ssl)
{
grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp ={"a","b"};
grpc::SslServerCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs="";
ssl_opts.pem_key_cert_pairs.push_back(pkcp);
creds = grpc::SslServerCredentials(ssl_opts);
}
else
creds=grpc::InsecureServerCredentials();
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, creds);
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
Error:
undefined reference to grpc::SslServerCredetials(grpc::ssl_opts)
I have included all the necessary files..
You code looks right. If you are adapting from examples/cpp/helloworld, you need to change -lgrpc++_unsecure to -lgrpc++ in the Makefile.
For the benefits of others, an example of using the tls/ssl code can be found at https://github.com/grpc/grpc/blob/master/test/cpp/interop/server_helper.cc#L50
I'm trying to implement an SSL server using the sample code from Qt documentation.
But after serverSocket->startServerEncryption(); is called, nothing happens - neither the encrypted() nor the sslErrors() signals are emitted (I've put breakpoints in the slots connected to them).
I test it by connecting an QSslSocket using connectToHostEncrypted to the port I'm listening on. The socket sends data, but my server does not respond (I'm using a TCP sniffer/proxy to see all the data being sent from client to server and from server to client).
This is my code for the server:
void SslServer::incomingConnection(int socketDescriptor)
{
qDebug() << "SslServer::incomingConnection()";
QSslSocket *serverSocket = new QSslSocket(this);
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));
connect(serverSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
serverSocket->startServerEncryption();
} else {
delete serverSocket;
}
}
And this is how I connect to it:
server = new SslServer(this);
server->listen(QHostAddress::Any, 3333);
QSslSocket *socket = new QSslSocket(this);
socket->connectToHostEncrypted("127.0.0.1", 3333);
According to the documentation:
Both the key and the local certificate are required if you are creating an SSL server socket.
And if you don't provide them, a "regular" error(QAbstractSocket::SocketError) signal is emitted by the socket. As you found out, the server doesn't send any data in that case.
SSH is not SSL. SSH client waits for initial data from server, while SSL client first sends data. So they both waiting for data from the other side.
To help myself learn socket programming, I made a very simple SMTP client (see code below), using some code from the the Wt SMTP Library
As an exercise, I thought I would take a shot at implementing a POP3 client. Using the Wikipedia as a reference, it looked as if you must simply connect to the server on port 110 and send commands (just like SMTP connects on port 25 and sends commands).
However, I have so far been unable to even connect, and basically just timeout in the get_response() every time. I tried connecting to pop.gmail.com with no luck.
I don't believe that you need to send any user/password/other information when the connection is first established? I expected to receive something along the lines of +OK POP3 Server Ready once I connect, and I can then send the USER and PASS commands.
My question is: Am I missing something during the connection phase? Am I trying to connect to a bad host (gmail)? If so, is there a better host than pop.gmail.com with which I can test? Or am I going about this entirely wrong?
#include <string>
#include <sstream>
#include <iostream>
#include <iterator>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int main()
{
boost::asio::io_service io_service;
tcp::socket socket(io_service);
tcp::resolver resolver(io_service);
tcp::resolver::query query("localhost", "25"); // Change this for POP3
tcp::resolver::iterator endpt_iter = resolver.resolve(query);
boost::system::error_code erc = boost::asio::error::host_not_found;
while(erc && endpt_iter != end)
{
socket.close();
socket.connect(*endpt_iter++, erc);
}
if(erc) { socket.close(); return }
std::cout << get_response(socket) << std::endl; // 220 <my-host-name> ESMTP Postfix
send(socket, "EHLO localhost\r\n");
std::cout << get_response(socket) << std::endl; // 250-<my-host-name>
return 0;
}
std::string get_response(tcp::socket& socket)
{
boost::asio::streambuf response;
for(;;)
{
std::string msg;
boost::asio::read_until(socket, response, "\r\n");
std::istream in(&response);
std::getline(in, msg);
return msg;
}
}
void send(tcp::socket& socket, std::string msg)
{
boost::asio::write(socket, boost::asio::buffer(msg));
}
Gmail requires SSL/TLS encryption on its POP3 and SMTP connections.
For POP3, you have to connect to port 995 and initiate an SSL/TLS handshake immediately upon connecting. Then you can read the server's initial +OK greeting from, and send commands to, the encrypted connection.
For SMTP, you have a couple of choices:
connect to port 465. Initiate an SSL/TLS handshake immediately upon connecting. Read the +OK greeting from, and send all commands to, the encrypted connection.
connect to port 587. Read the +OK greeting from, and send EHLO and STARTTLS commands to, the unencrypted connection. Initiate the SSL/TLS handshake. Send a new EHLO command, and other commands, to the encrypted connection.