Google assistant gRPC call hung - grpc

Server doesn't reply when a GRPC call is made to "embeddedassistant.googleapis.com". I see the request being received at google server end when I check the Google API web interface.
I set the request with proper configuration (when I set wrong configuration I do get error message from server). Is there anything I'm missing here?
std::string Converse(const std::string& user) {
AudioInConfig audio_in_config;
audio_in_config.set_encoding(google::assistant::embedded::v1alpha1::AudioInConfig_Encoding_FLAC);
audio_in_config.set_sample_rate_hertz(16000);
AudioOutConfig audio_out_config;
audio_out_config.set_encoding(google::assistant::embedded::v1alpha1::AudioOutConfig_Encoding_MP3);
audio_out_config.set_sample_rate_hertz(16000);
audio_out_config.set_volume_percentage(50);
ConverseState converse_state;
const char * conversation_state = "a";
converse_state.set_conversation_state(conversation_state);
ConverseConfig config;
config.set_allocated_audio_in_config(&audio_in_config);
config.set_allocated_audio_out_config(&audio_out_config);
config.set_allocated_converse_state(&converse_state);
ConverseRequest request;
request.set_allocated_config(&config);
ConverseResponse reply;
ClientContext context;
auto status = stub_->Converse(&context, request, &reply);
config.release_audio_in_config();
config.release_audio_out_config();
config.release_converse_state();
request.release_config();
// Act upon its status.
if (status.ok()) {
return reply.result().conversation_state();
} else {
std::cout << "Error: " << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
return "";
}

Why have you set the conversation_state to "a". It should be in bytes or empty. You also need to send an audio data captured depending upon the situation. You can do that by including the ALSA sound API in C++ in your code.
The conversation_state value returned in the prior ConverseResponse. Omit (do not set the field) if there was no prior ConverseResponse. If there was a prior ConverseResponse, do not omit this field; doing so will end that conversation (and this new request will start a new conversation).
You can see from here:-
https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha1

Related

POCO - Socket Reactor - Avoid Polling When Client Ab Ends

When a client ab ends the reactor seems to indefinitely go into a polling state resulting in roughly 15% of the processor being used. If the client reconnects I'm still losing that 15%, I'm trying to determine what is lacking in my code to handle this properly.
When the client ab ends _socket.available() immediately returns false so in the else block I'm attempting to do the right thing. Doing the same thing I do when a client terminates normally, 'delete this' eliminates the processor issue but the next time a client connects I get an allocation error, I'd like to understand why that is, what's the difference? Just putting a sleep in there solves everything but onSocketReadable continues to be called with _socket.available() == false, so it remains as a sort of orphaned active reactor, what am I missing? I also tried stopping the reactor, that stops the processor use but the restarted client will no longer connect, there's something I don't understand there also, seems like a new reactor would be created just as it was initially?
void onSocketReadable(const AutoPtr<ReadableNotification>& pNf)
{
// some socket implementations (windows) report available
// bytes on client disconnect, so we double-check here
if (_socket.available())
{
// No FIFO for now
//int len = _socket.receiveBytes(_fifoIn);
char* buffer = new char[65535];
memset(buffer, 0, 65535);
_socket.setReceiveBufferSize(65535);
int n = _socket.receiveBytes(buffer, 65535);
std::string json = buffer;
delete [] buffer;
if (json == "SHUTDOWN\r\n")
{
delete this;
return;
}
try
{
std::string result = _processor.process(json,_sm);
result.append("\r\n");
_socket.sendBytes(result.data(), (int)result.length());
}
catch (Poco::Exception& e)
{
std::cout << e.message();
}
}
else
{
// delete this;
// return;
// _reactor.stop();
Sleep(10);
}
}

Setting ASIO no_delay option

I'm having troubles setting the no_delay option on an asio socket. The following code runs well, except for the delay. My server receives the messages only after the 5000 ms expire.
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using namespace boost::asio;
struct Client
{
io_service svc;
ip::tcp::socket sock;
Client() : svc(), sock(svc)
{
ip::tcp::resolver resolver(svc);
ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323"));
connect(sock, endpoint);
}
void send(std::string const& message) {
sock.send(buffer(message));
}
};
int main()
{
Client client;
client.send("hello world\n");
client.send("bye world\n");
boost::this_thread::sleep_for(boost::chrono::milliseconds(5000));
}
When trying to add a delay I have a few options:
1) Add the option before connection:
Client() : svc(), sock(svc)
{
ip::tcp::resolver resolver(svc);
ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323"));
sock.set_option(ip::tcp::no_delay(true));
connect(sock, endpoint);
}
However this throws set_option: Bad file descriptor
2) Add the option after the connection:
Client() : svc(), sock(svc)
{
ip::tcp::resolver resolver(svc);
ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323"));
connect(sock, endpoint);
sock.set_option(ip::tcp::no_delay(true));
}
However in this case, the option has no effect and I still see the delay. According to boost::asio with no_delay not possible? , I need to set the option after I've opened the socket but before I've connected the socket. So I've tried this:
Client() : svc(), sock(svc)
{
ip::tcp::endpoint endpoint( ip::address::from_string("127.0.0.1"), 32323);
sock.open(ip::tcp::v4());
sock.set_option(ip::tcp::no_delay(true));
sock.connect(endpoint);
}
However, I still see no effect. How can I set this option?
Edit: It's possible that I am not setting the option correctly on the server-side. This is the complete server code:
#include <boost/asio.hpp>
#include <iostream>
int main() {
boost::asio::io_service io_service;
boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 32323));
boost::asio::ip::tcp::socket socket(io_service);
acceptor.accept(socket);
socket.set_option(boost::asio::ip::tcp::no_delay(true));
boost::asio::streambuf sb;
boost::system::error_code ec;
while (boost::asio::read(socket, sb, ec)) {
std::cout << "received:\n" << &sb;
}
}
The client is properly setting the ip::tcp::no_delay option. However, the delay being observed is not the result of this option. Instead, it is the result of the server attempting to read more data than the client has sent, and when the client exits after sleeping 5000ms, the server's read operation completes with an error.
The read() operation initiated by the server will complete when either it has read streambuf.max_size() bytes or an error occurs. The streambuf's max size defaults to std::numeric_limits<std::size_t>::max() and can be configured in its constructor. In this case, the server attempts to read std::numeric_limits<std::size_t>::max() bytes, but the client only sends 22 bytes, sleeps 5000ms, then closes the socket. When the server observes that connection has closed, the read() operation completes with 22 bytes read and an error code of boost::asio::error::eof.

QNetworkReply behavior againt local site with authentication

i'm using QNetworkReply in order to issue a simple GET request to my router interface. Basically if the post data is empty i issue a GET otherwise i will issue a POST. Let's stick with the GET
QString url=ui->lineEdit_url->text();
QString paras=ui->pTextEdit_paras->toPlainText();
qDebug()<< "paras" << paras;
QByteArray post_data;
post_data.append(paras);
QNetworkRequest request = QNetworkRequest(QUrl(url));
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
if(post_data.isEmpty())
{
//nam->head(request);
nam->get(request);
}
else
{
nam->post(request,post_data);
}
now with
...
connect(nam,
SIGNAL(finished(QNetworkReply*)),
this,
SLOT(finished(QNetworkReply*)));
...
void HttppostWindow::finished(QNetworkReply *reply)
{
if(reply->error() == QNetworkReply::NoError)
{
ui->textEdit_result->setText(QObject::tr(reply->readAll()));
}
else
{
ui->textEdit_result->setPlainText(reply->errorString());
}
}
i show the answer in the ui.
Right now the local interface asks for a login and a pw. The problem is that the retrieved text with the GET command is the one that the interface would show if the user would have insterted a wrong password (autentication failed please try again and so on).
Moreover with the code nam->head(request) i should be able to retrieve the header, but the content of replyAll is empty.
Any ideas?
After nam->head(request) you don't need to use reply->readAll().
Instead of this you should use methods like:
QByteArray rawHeader(const QByteArray &headerName) const;
QList<QByteArray> rawHeaderList() const;
const QList<RawHeaderPair> &rawHeaderPairs() const;
With this methods you can view content of your head request.
Also your sample code has memory leak. You should delete the reply whis reply->deleteLater() inside your finished slot.

Nginx filtering message before proxy

I have been digging into creating a custom filtering module written in C that can process post messages. Read the json payload, make a decision whether to proxy the message or return a 204 to the client.
I am having trouble reading the payload of the message, I have read through quite a few of the modules but am missing something. I have tried quite a few ways to parse the payload but can't seem to figure out how to just simply print it.
I have read through the echo module, redis module, Evan Miller's documentation, etc.
I know that I need to read the full message before I can process the payload but the callback has got me confused. I don't really understand the callback in ngx_http_read_client_request_body. I have tried to read the code but there really is almost no documentation in the code.
In the code below I have tried multiple things to get the request body, I tried reading r->request_body->buf, bufs once the full body was read. When I try to print the request body, I get segfault. I think the echo module would have been the closest to what I wanted to do but I got confused in the ngx_http_echo_wev_handler on how it was processing the request.
static ngx_int_t ngx_http_ortb_handler(ngx_http_request_t *r) {
ngx_int_t rc;
ngx_flag_t read_body;
if (r->method != NGX_HTTP_POST) {
read_body = 1;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Received Post");
if (read_body) {
rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "return code %ld", rc);
// What do I need to do here to read the body.
} else {
r->main->count++;
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
return rc;
}
ngx_http_upstream_init(r);
}
return NGX_DECLINED;
}

QtWebkit: How to check HTTP status code?

I'm writing a thumbnail generator as per an example in the QtWebkit documentation. I would like to avoid screenshots of error pages such as 404 not found or 503 Internal server error.
However, the QWebPage::loadFinished() signal is always emitted with ok = true even when the page gives an HTTP error. Is there a way in QtWebkit to check the HTTP status code on a response?
Turns out you need to monitor the QNetworkAccessManager associated with your QWebPage and wait for a finished(...) signal. You can then inspect the HTTP response and check its status code by asking for the QNetworkRequest::HttpStatusCodeAttribute attribute.
It's better explained in code:
void MyClass::initWebPage()
{
myQWebPage = new QWebPage(this);
connect(
myQWebPage->networkAccessManager(), SIGNAL(finished(QNetworkReply *)),
this, SLOT(httpResponseFinished(QNetworkReply *))
);
}
void MyClass::httpResponseFinished(QNetworkReply * reply)
{
switch (reply->error())
{
case QNetworkReply::NoError:
// No error
return;
case QNetworkReply::ContentNotFoundError:
// 404 Not found
failedUrl = reply->request.url();
httpStatus = reply->attribute(
QNetworkRequest::HttpStatusCodeAttribute).toInt();
httpStatusMessage = reply->attribute(
QNetworkRequest::HttpReasonPhraseAttribute).toByteArray();
break;
}
}
There are more NetworkErrors to choose from, e.g. for TCP errors or HTTP 401.
This is what I'm using in a porting project. It checks the reply and decides to start backing off making request or not. The backing off part is in progress but I left the comments in.
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
Q_CHECK_PTR(reply);
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (!statusCode.isNull() && statusCode.toInt() >= 400){
//INVALID_SERVER_RESPONSE_BACKOFF;
qDebug() << "server returned invalid response." << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
return;
}else if (!statusCode.isNull() && statusCode.toInt() != 200){
//INVALID_SERVER_RESPONSE_NOBACKOFF;
qDebug() << "server returned invalid response." << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
return;
}

Resources