7 #include <QJsonDocument>
44 , _attemptInterval(interval)
48 , _codeDirectory(this)
89 connect( &
_ping, SIGNAL(timeout()),
124 QMutexLocker l(&
_lock);
127 QMap<postID, VFS_request *>::const_iterator it;
161 QAbstractSocket::SocketState s =
_socket->state();
163 if (s==QAbstractSocket::ConnectedState)
186 QAbstractSocket::SocketState s =
_socket->state();
188 if (s!=QAbstractSocket::ConnectingState && s!=QAbstractSocket::ConnectedState)
195 QSslSocket *_sslSocket =
dynamic_cast<QSslSocket *
> (
_socket);
206 if (s==QAbstractSocket::ConnectedState)
250 QJsonDocument d( m );
251 QByteArray message = d.toJson();
312 int count = r->
_metadata.value(
"subscriptions").toInt(1);
314 if (r->
_metadata.contains(
"resubscription") && r->
_metadata[
"resubscription"].toBool())
347 QByteArray message = r->
toJson(i,
true);
407 #ifdef COMPRESS_TCP_MOUNT
408 message = qUncompress(message);
409 if (message.length() == 0)
410 VFS::ERROR(
"(2) Uncompressed message size was 0.");
414 printf(
"%s received: %s\n",qUtf8Printable(
className()),qUtf8Printable(message));
419 QJsonDocument d = QJsonDocument::fromJson(message);
420 QJsonObject o = d.object();
428 QString address = o[
"metadata"].toObject()[
"sessionid"].toString();
438 m[
"metadata"] = o[
"metadata"];
444 VFS::ERROR( QString(
"Session not found: '%1'. Cannot resolve session request.").arg(address) );
448 m[
"data"] = QJsonValue::Null;
449 m[
"metadata"] = o[
"metadata"];
464 if (o.contains(
"sourceID"))
466 postID sourceID =
static_cast<postID>(o[
"sourceID"].toInt());
480 printf(
"requestID %d does not exist for notifyExceptions.\n",sourceID);
505 VFS::WARN(
"Deprecate code directory requests!");
512 bool willIssueMounted =
false;
513 QString issueMountedPath =
"";
518 if (r->
_metadata.contains(
"resubscription") && r->
_metadata[
"resubscription"].toBool())
521 willIssueMounted =
true;
536 if (willIssueMounted)
540 VFS::WARN( QString(
"Received a message with an unknown id: %1. Ignoring.").arg(
id), 0,
className() );
553 printf(
"%s sends: %s\n",qUtf8Printable(
className()),qUtf8Printable(message));
556 #ifdef COMPRESS_TCP_MOUNT
557 message = qCompress(message);
579 QMutexLocker l(&
_lock);
583 QMutableMapIterator<QString, VFS_subscriptionOrigin > ito(
_subscribers);
584 while (ito.hasNext())
588 QMutableMapIterator<QString, VFS_subscriptionCounter > it(ito.value());
593 if (it.value().contains(subscriber))
594 c=it.value()[subscriber];
601 m[
"unsubscriptions"] = c;
604 VFS::LOG( QString(
"unsubscribeAll removed '%1' %2 (%3 remote)").arg(ito.key()).arg(
className()).arg(c), 9 );
626 QMutexLocker l(&
_lock);
633 VFS_subscriptionType::iterator it =
_subscribers.begin();
634 VFS_subscriptionOrigin::iterator ito;
670 VFS::WARN(
"Skipping resubscribe on non-existent node\n" );
705 {
VFS::WARN(QString(
"Skipping request for non-node 0x%1").arg((quintptr)r->
_origin, QT_POINTER_SIZE * 2, 16, QChar(
'0')),9,
className());
723 QMutexLocker l(&
_lock);
726 d[
"mounted"] =
false;
728 VFS_subscriptionType::iterator it =
_subscribers.begin();
729 VFS_subscriptionOrigin::iterator ito;
790 VFS::ERROR( QString(
"Could not find available id for request. Aborting."), 0,
className() );
832 QMutexLocker l(&
_lock);
845 QMutexLocker l(&
_lock);
#define POST_ID_CODE_DIRECTORY
#define POST_ID_SESSION_DATA
QMap< VFS_node *, qint32 > VFS_subscriptionCounter
QMap< QString, VFS_subscriptionCounter > VFS_subscriptionOrigin
#define VFS_TCP_MOUNT_PING_TIME_MS
static char * get(QString which="")
Fetch an icon from the library.
VFS_node is the base class from which all other VFS_node classes derive.
virtual void executeRequest(VFS_request *t)
Based on the VFS_request::requestType, execute the function associated with an operation.
virtual VFS_request * createRequest(VFS_request::requestType type, QString path, QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false)
Create a new VFS_request with this object as _origin.
virtual void issueResponse(VFS_request *t)
Once a request has been completed, issue a response.
virtual void unsubscribeAll(VFS_node *n)
Remove all references to a subscriber from this node.
virtual void issueRequest(VFS_request *t)
A convenience function.
static bool __isNode(VFS_node *)
Check to see if a node is in the global registry.
void unmounted(VFS_node *self)
Emitted when a node is unmount()ed.
void diff(VFS_node *origin, VFS_request *t)
Emit a diff, which will trigger notifySubscribers() for a mounted node.
QString className()
Return the class name of a node.
VFS_subscriptionType _subscribers
This node's subscribers. These subscribers will receive diff notifications.
QMutex _lock
A recursive mutex that is local to this node.
virtual void applyDiff(VFS_request *r)
Apply a diff received via subscription.
virtual void unsubscribe(VFS_request *r)
Remove an entry from this node's _subscription list.
The base class for all requests between nodes.
static const char * requestTypeStrings[]
A printable string for each request type.
@ report
provide node report, for debugging (12)
@ unsubscribe
unsubscribe from a path (10)
@ codeDirectory
request a listing of code served by a node (16)
@ subscribe
subscribe to a path (9)
VFS_node * _origin
the origin of the request
requestType _requestType
the action this request is performing or requesting
QString _initialPath
the target path when the request was made (relative to the responder)
QStringList _prefixPath
the prefix elements found while searching for the target
QString _user
who initiated this request, mostly for logging
virtual void fromJsonObject(QJsonObject json, bool includeInitialPath=false)
Deserialize a JSON string into a VFS_request.
QString _path
the target path remnant... the remaining path element once the request has found its target
bool _isCallback
whether or not to issue a response (IE, another request is chained to this request,...
QString _originPath
the subpath of the origin node
QList< notifyException > _notifyExceptions
a list of nodes not to send responses to for this transaction. For instance if a node submits to a no...
bool _success
if the request was successfully completed
QJsonDocument _data
the request payload
virtual QByteArray toJson(postID id=0, bool ignoreSuccess=false, bool includeInitialPath=false)
Serialize this request.
QJsonObject _metadata
the request payload
The VFS_session object represents a single session.
QJsonObject toJson()
Return a json object with the salient data from this session.
static VFS_session * fetchSession(QString address)
Try to resolve and cast a string address to a VFS_session.
void connected()
Emitted when a connection has been made.
QString _address
The address resolved by peerAddress(), or the address to connect to.
QTcpSocket * _socket
The socket connection.
void readyMessage(QByteArray message)
Emitted when a message is ready for processing.
bool _initialized
Has this node been initialized?
virtual void init()
DOCME.
quint16 _port
The port to connect to.
virtual void writeMessage(QByteArray data)
DOCME.
void disconnected()
Emitted when a connection has been lost.
virtual void registerDirectory(QJsonObject d)
Register entries to the code directory.
virtual void unregisterDirectory()
Unregister all entries in this directory.
void timerEvent(QTimerEvent *e=nullptr)
DOCME.
void issueUnmounted()
VFS_tcp_mount::issueUnmounted.
QString _path
The path to this node.
void attemptConnection()
DOCME.
static QList< VFS_tcp_mount * > _mounts
The list of existing mounts.
virtual void stopPing()
DOCME.
QTimer _ping
The ping timer object.
void sendUnmountedRequests()
DOCME.
postID _currentID
The current VFS_request_id.
void refreshSubscriptions()
Resubscribe to what had been previously subscribed.
virtual QByteArray icon()
Fetch the icon for this node.
void sendMessage(QByteArray message)
send a message over the line
int _timerID
The ID of the connection timer.
bool isMounted()
Return the state of _mounted.
virtual void startPing()
DOCME.
QString _name
The name of this node for logging purposes.
bool _mounted
Is this mounted?
virtual void sendPing()
DOCME.
void issueMounted(QString path)
VFS_tcp_mount::issueMounted.
QMap< postID, VFS_request * > _requests
Outstanding VFS_requests.
postID getNewRequestID()
DOCME.
virtual void startConnecting()
DOCME.
virtual void unsubscribeAll(VFS_node *n)
Remove all references to a subscriber from this node.
QString path()
Return the path to this node.
virtual void receiveMessage(QByteArray message)
virtual VFS_node * find(VFS_request *r)
Always return 'this'.
virtual bool isContainer()
virtual void stopConnecting()
DOCME.
static QMutex _mountsLock
A mutex for modifying the _mounts entry.
virtual void executeRequest(VFS_request *r)
DOCME.
VFS_tcp_mount_directory _codeDirectory
The directory of code available when mounted.
QList< VFS_request * > _unmountedRequests
Requests to submit when re-mounted.
int _attemptInterval
The interval to attempt (re)connections.
Q_INVOKABLE VFS_tcp_mount(QString name, QString path, QString address, quint16 port, quint16 interval=3000, bool ssl=false, QString sslCertPath="")
VFS_tcp_mount constructor.
static void LOG(QString message, int level=0, QString user="server")
Send a message to the VFS::_messages VFS_stream.
static void ERROR(QString message, int level=0, QString user="server")
Send a message to the VFS::_errors VFS_stream.
static void WARN(QString message, int level=0, QString user="server")
Send a message to the VFS::_warnings VFS_stream.
message(m)
Change the message of an existing arrowMessage.
setter name
a setter DOCME
getter path
a getter DOCME
QString cleanPath(QString path)
Clean and normalize a VFS path.