75ce626532
Using static vars meant all connections were using the same static vars! A bug that has existed since 2009! This code is ugly, but since it is such a fundamental piece of code for every operation, no refactoring is being done except to convert the static vars to data members renaming where required to avoid name conflicts. The one exception is that `cumLen` which was a per hdr.type variable is now a single data member across all types. Since for a single connection messages will be sequential this is expected to work (fingers crossed!) For the future we should look at replacing the custom RPC code with GRPC (issue #305). Fixes #304
129 lines
4.1 KiB
C++
129 lines
4.1 KiB
C++
/*
|
|
Copyright (C) 2010 Srivats P.
|
|
|
|
This file is part of "Ostinato"
|
|
|
|
This is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
#ifndef _PB_RPC_CHANNEL_H
|
|
#define _PB_RPC_CHANNEL_H
|
|
|
|
#include <QString>
|
|
#include <QTcpServer>
|
|
#include <QTcpSocket>
|
|
|
|
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
|
#include <google/protobuf/message.h>
|
|
#include <google/protobuf/descriptor.h>
|
|
#include <google/protobuf/service.h>
|
|
|
|
#include "pbrpccommon.h"
|
|
#include "pbrpccontroller.h"
|
|
|
|
class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel
|
|
{
|
|
Q_OBJECT
|
|
|
|
// If isPending is TRUE, then controller, done, response
|
|
// and pendingMethodId correspond to the last method called by
|
|
// the service stub
|
|
bool isPending;
|
|
int pendingMethodId;
|
|
|
|
// controller, done, response are set to the corresponding values
|
|
// passed by the stub to CallMethod(). They are reset to NULL when
|
|
// we get a response back from the server in on_mpSocket_readyRead()
|
|
// after calling done->Run().
|
|
|
|
/*! \todo (MED) : change controller, done and response to references
|
|
instead of pointers? */
|
|
const ::google::protobuf::MethodDescriptor *method;
|
|
::google::protobuf::RpcController *controller;
|
|
::google::protobuf::Closure *done;
|
|
::google::protobuf::Message *response;
|
|
|
|
typedef struct _RpcCall {
|
|
const ::google::protobuf::MethodDescriptor *method;
|
|
::google::protobuf::RpcController *controller;
|
|
const ::google::protobuf::Message *request;
|
|
::google::protobuf::Message *response;
|
|
::google::protobuf::Closure *done;
|
|
} RpcCall;
|
|
QList<RpcCall> pendingCallList;
|
|
|
|
const ::google::protobuf::Message ¬ifPrototype;
|
|
::google::protobuf::Message *notif;
|
|
|
|
QString mServerHost;
|
|
quint16 mServerPort;
|
|
QTcpSocket *mpSocket;
|
|
|
|
::google::protobuf::io::CopyingInputStreamAdaptor *inStream;
|
|
::google::protobuf::io::CopyingOutputStreamAdaptor *outStream;
|
|
|
|
uchar sendBuffer_[4096];
|
|
|
|
// receive RPC related vars
|
|
bool parsing{false};
|
|
QByteArray buffer; // used for response type messages
|
|
QByteArray errorBuf; // used for error type messages
|
|
quint32 cumLen{0};
|
|
quint16 type;
|
|
quint16 methodId;
|
|
quint32 len;
|
|
|
|
public:
|
|
PbRpcChannel(QString serverName, quint16 port,
|
|
const ::google::protobuf::Message ¬ifProto);
|
|
~PbRpcChannel();
|
|
|
|
void establish();
|
|
void establish(QString serverName, quint16 port);
|
|
void tearDown();
|
|
|
|
const QString serverName() const
|
|
{
|
|
return mpSocket->peerName();
|
|
}
|
|
quint16 serverPort() const { return mServerPort; }
|
|
|
|
QAbstractSocket::SocketState state() const
|
|
{ return mpSocket->state(); }
|
|
|
|
void CallMethod(const ::google::protobuf::MethodDescriptor *method,
|
|
::google::protobuf::RpcController *controller,
|
|
const ::google::protobuf::Message *req,
|
|
::google::protobuf::Message *response,
|
|
::google::protobuf::Closure* done);
|
|
|
|
signals:
|
|
void connected();
|
|
void disconnected();
|
|
void error(QAbstractSocket::SocketError socketError);
|
|
void stateChanged(QAbstractSocket::SocketState socketState);
|
|
|
|
void notification(int notifType, ::google::protobuf::Message *notifData);
|
|
|
|
private slots:
|
|
void on_mpSocket_connected();
|
|
void on_mpSocket_disconnected();
|
|
void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState);
|
|
void on_mpSocket_error(QAbstractSocket::SocketError socketError);
|
|
|
|
void on_mpSocket_readyRead();
|
|
};
|
|
|
|
#endif
|