Remoto - VFS: VFS_tcp_mount.cpp Source File
Remoto - VFS
VFS_tcp_mount.cpp
Go to the documentation of this file.
1 
2 #include "VFS_tcp_mount.h"
3 #include "VFS_base/VFS_icons.h"
4 #include "utilities/rutils.h"
5 #include "VFS_creator.h"
6 
7 #include <QJsonDocument>
8 #include <QJsonObject>
9 
10 #include "VFS.h"
11 
23 QList<VFS_tcp_mount *> VFS_tcp_mount::_mounts;
24 
25 
40  VFS_tcp_mount::VFS_tcp_mount(QString name, QString path, QString address, quint16 port, quint16 interval, bool ssl, QString sslCertPath)
41 : VFS_tcp_client(address,port,ssl,sslCertPath)
42 , _name(name)
43 , _path(path)
44 , _attemptInterval(interval)
45 , _timerID(0)
46 , _mounted(false)
47 , _currentID(POST_ID_START)
48 , _codeDirectory(this)
49 {
50  QMutexLocker l(&_mountsLock);
51 
52  _mounts << this;
53 }
54 
56 {
57  QMutexLocker l(&_mountsLock);
58 
59  _mounts.removeAll(this);
60 }
61 
62 
70 {
71  if (_initialized)
72  return;
73 
74  connect( this, SIGNAL(connected()),
75  this, SLOT(stopConnecting()) );
76 
77  connect( this, SIGNAL(connected()),
78  this, SLOT(startPing()) );
79 
80  connect( _socket, SIGNAL(disconnected()),
81  this, SLOT(startConnecting()) );
82 
83  connect( _socket, SIGNAL(disconnected()),
84  this, SLOT(stopPing()) );
85 
86  connect( this, SIGNAL(readyMessage(QByteArray)),
87  this, SLOT(receiveMessage(QByteArray)));
88 
89  connect( &_ping, SIGNAL(timeout()),
90  this, SLOT(sendPing()) );
91 
94 
96 }
97 
98 
105 void VFS_tcp_mount::timerEvent(QTimerEvent *)
106 {
108 
109  //more stuff here...?
110 }
111 
112 
120 {
121  if (_mounted)
122  { VFS::WARN( QString("Lost conection to '%1:%2'... reconnecting.").arg(_address).arg(_port), 0, className() );
123 
124  QMutexLocker l(&_lock);
125 
126  VFS_request *r;
127  QMap<postID, VFS_request *>::const_iterator it;
128  for (it=_requests.begin();it!=_requests.end();it++)
129  { r = it.value();
130  r->_success = false;
131  issueResponse(r);
132  //it.value()->fail();
133  }
134 
135  _requests.clear();
136 
138 
139  issueUnmounted();
140  }
141 
142  if (!_timerID)
143  _timerID = startTimer(_attemptInterval);
144 
145  _mounted = false;
146 }
147 
148 
156 {
157  if(_timerID)
158  {
159  killTimer(_timerID);
160 
161  QAbstractSocket::SocketState s = _socket->state();
162 
163  if (s==QAbstractSocket::ConnectedState)
164  {
165  VFS::LOG( QString("Connected to '%1' @ '%2:%3' (%4)").arg(_name).arg(_address).arg(_port).arg(_ssl?"secure":"insecure"), 0, className() );
166  _mounted = true;
167 
170  //issueMounted(); // can't do this here... have to wait for subscription to complete
171  }
172  }
173 
174  _timerID = 0;
175 }
176 
177 
185 {
186  QAbstractSocket::SocketState s = _socket->state();
187 
188  if (s!=QAbstractSocket::ConnectingState && s!=QAbstractSocket::ConnectedState)
189  //if (s == QAbstractSocket::UnconnectedState)
190  {
191  VFS::LOG( QString("Attempting to mount '%1 @ %2:%3' (%4)...").arg(_name).arg(_address).arg(_port).arg(_ssl?"secure":"insecure"), 9, className() );
192 
193  if (_ssl)
194  {
195  QSslSocket *_sslSocket = dynamic_cast<QSslSocket *> (_socket);
196  _sslSocket->connectToHostEncrypted(_address,_port);
197  }
198  else
199  {
200  _socket->connectToHost(_address,_port);
201  }
202  }
203  else
204  {
205  VFS::WARN( QString("Already connected or connecting '%1:%2' (%3)").arg(_address).arg(_port).arg(s), 0, className() );
206  if (s==QAbstractSocket::ConnectedState)
207  stopConnecting();
208  }
209 }
210 
211 
219 {
221 }
222 
223 
231 {
232  _ping.stop();
233 }
234 
235 
243 {
244  QJsonObject m;
245 
246  m["id"] = POST_ID_PING;
247 
248  //QString message = json::encode(m);
249 
250  QJsonDocument d( m );
251  QByteArray message = d.toJson();
252 
253  sendMessage(message);
254 }
255 
256 
265 {
266  return true;
267 }
268 
269 
277 {
278  if (_mounted)
279  {
280  postID i = getNewRequestID();
281 
282  //remember the callback object for when the response comes
283  _requests.insert(i,r);
284  //printf("request list length: %d\n",_requests.size());
285 
286  switch(r->_requestType)
287  {
288  case VFS_request::submit: {
289  //QString subscriberSubpath = rutils::cleanPath( r->_originPath );
290  // r->_notifyExceptions << notifyException(r->_origin,r->_initialPath);
291  //r->_notifyExceptions << notifyException(this,r->_initialPath);
292  //r->_notifyExceptions << notifyException(this,subscriberSubpath);
293  //r->_notifyExceptions << notifyException(this,r->_path);
294  //r->_notifyExceptions << notifyException(r->_origin,r->_path);
295  //printf("submit exception: %p %s\n",r->_origin,qUtf8Printable(r->_path));
296  }
297 
298  break;
299 
300  case VFS_request::subscribe: {
301  //we want a modified version of subscribe here, where the entry is created but read() and metadata() are not called.
302  VFS_node *subscriber = r->_origin;
303 
304  if (!__isNode(subscriber))
305  {
306  _requests.remove(i);
307  delete r;
308  return;
309  }
310 
311  QString subscriberSubpath = rutils::cleanPath( r->_originPath );
312  int count = r->_metadata.value("subscriptions").toInt(1);
313 
314  if (r->_metadata.contains("resubscription") && r->_metadata["resubscription"].toBool())
315  { count = 0;
316  //r->_metadata.remove("resubscription");
317  }
318 
319  _subscribers[r->_path][subscriberSubpath][subscriber]+=count; //will create default/empty values as needed.
320  connect( subscriber, SIGNAL(unmounted(VFS_node *)), this, SLOT(unsubscribeAll(VFS_node *)), Qt::UniqueConnection );
321 
322  //FIXME: should we just do a subscribe(r) with flags to skip metadata() and read()?
323  //this version will call read() and metadata(), which we don't want
324  //subscribe(r);
325  }
326 
327  break;
328 
330  unsubscribe(r);
331  }
332  break;
333 
334  case VFS_request::report: {
336  //report(r);
337  //issueResponse(r);
338  _requests.remove(i);
339  //delete r;
340  return;
341  }
342  //break;
343 
344  default: break;
345  }
346 
347  QByteArray message = r->toJson(i,true);//,initial);
348 
349  sendMessage(message);
350 
351  startPing(); //restart the _ping timer
352  }
353  else
354  {
355  switch(r->_requestType)
356  {
357  /*
358  case VFS_request::none:
359  // case VFS_request::subscribe:
360  {
361  //we want a modified version of subscribe here, where the entry is created but read() and metadata() are not called.
362  VFS_node *subscriber = r->_origin;
363  QString subscriberSubpath = rutils::cleanPath( r->_originPath );
364  int count = r->_metadata.value("subscriptions").toInt(1);
365  _subscribers[r->_path][subscriberSubpath][subscriber]+=count; //will create default/empty values as needed.
366  connect( subscriber, SIGNAL(unmounted(VFS_node *)), this, SLOT(unsubscribeAll(VFS_node *)), Qt::UniqueConnection );
367 
368  r->_dontDelete = true;
369  issueResponse(r);
370 
371  VFS_tcp_client::executeRequest(r);
372  }
373 
374  break;
375  */
376 
377  // case VFS_request::none:
378  // case VFS_request::subscribe:
379  // case VFS_request::unsubscribe:
380  // case VFS_request::diff:
381  case VFS_request::report:
382  // case VFS_request::acl:
384  break;
385 
386  default: //don't call VFS_node::executeRequest()...
387  //and don't issueResponse()...
388  //let the stored _requests wait for the response from the other end
389 
390  VFS::WARN( QString("%1 '%2' request on '%3' queued for when mounted.").arg(className()).arg(VFS_request::requestTypeStrings[r->_requestType]).arg(r->_path), 9, r->_user );
391  _unmountedRequests << r;
392  break;
393  }
394  }
395 }
396 
397 
406 {
407  #ifdef COMPRESS_TCP_MOUNT
408  message = qUncompress(message);
409  if (message.length() == 0)
410  VFS::ERROR("(2) Uncompressed message size was 0.");
411  #endif
412 
413  #ifdef SHOW_JSON
414  printf("%s received: %s\n",qUtf8Printable(className()),qUtf8Printable(message));
415  #endif
416 
417  startPing(); //restart the _ping timer
418 
419  QJsonDocument d = QJsonDocument::fromJson(message);
420  QJsonObject o = d.object();
421 
422  postID id = static_cast<postID>(o["id"].toInt());
423 
424  if (id == POST_ID_SESSION_DATA)
425  {
426  //printf("received session data request: %s\n",qUtf8Printable(d.toJson()));
427 
428  QString address = o["metadata"].toObject()["sessionid"].toString();
430 
431  if (s)
432  {
433  //printf("found session!\n%s\n",qUtf8Printable(QJsonDocument(s->toJson()).toJson()));
434 
435  QJsonObject m;
436  m["id"] = POST_ID_SESSION_DATA;
437  m["data"] = s->toJson();
438  m["metadata"] = o["metadata"];
439 
440  sendMessage( QJsonDocument(m).toJson() );
441  }
442  else
443  {
444  VFS::ERROR( QString("Session not found: '%1'. Cannot resolve session request.").arg(address) );
445 
446  QJsonObject m;
447  m["id"] = POST_ID_SESSION_DATA;
448  m["data"] = QJsonValue::Null;
449  m["metadata"] = o["metadata"];
450 
451  //sendMessage( QJsonDocument(m).toJson() );
452  }
453  }
454  else if (id == POST_ID_DIFF)
455  {
456  //printf("MOUNT RECEIVED DIFF\n");
457  VFS_request r;
458  r.fromJsonObject(o,true);
459 
460  // if the origin of this diff was a submit,
461  // this field will contain the ID of that submit request,
462  // which will refer to the id in _requests.
463  // This will allow us to copy _notifyExceptions from the submit request on this new request
464  if (o.contains("sourceID"))
465  {
466  postID sourceID = static_cast<postID>(o["sourceID"].toInt());
467  //printf("sourceID: %d\n",sourceID);
468 
469  if (_requests.contains(sourceID))
470  {
471  VFS_request *sr = _requests[sourceID];
473  r._initialPath = sr->_initialPath;
474 
475  // printf("copied notifyExceptions\n");
476  // for (int i=0;i<r._notifyExceptions.length();i++)
477  // printf(" notify exception: %p %s\n",r._notifyExceptions[i].first,qUtf8Printable(r._notifyExceptions[i].second));
478  }
479  else
480  printf("requestID %d does not exist for notifyExceptions.\n",sourceID);
481  }
482 
483  applyDiff(&r);
484  //emit diff(this,&r);
485 
486  return;
487  }
488  else if (id == POST_ID_CODE_DIRECTORY)
489  {
490  VFS_request r;
491  r.fromJsonObject(o,true);
492 
495 
496  return;
497  }
498  else if (_requests.contains(id))
499  {
500  VFS_request *r = _requests.take(id);
501  r->fromJsonObject(o);
502 
504  {
505  VFS::WARN("Deprecate code directory requests!");
506  _codeDirectory.registerDirectory((r->_data.object()));
507  delete r;
508 
509  return;
510  }
511 
512  bool willIssueMounted = false;
513  QString issueMountedPath = "";
514 
515  // if this is a resubscription, we need to tell the client that the pane or resource has been mounted.
517  {
518  if (r->_metadata.contains("resubscription") && r->_metadata["resubscription"].toBool())
519  {
520  //issueMounted(r->_initialPath);
521  willIssueMounted = true;
522  //issueMountedPath = r->_initialPath;
523  //issueMountedPath = r->_path;
524  issueMountedPath = r->_initialPath.mid(_path.length()+1);
525 
526  //printf("RESUBSCRIBE: %s %p\n",qUtf8Printable(r->_initialPath),r->_origin);
527  //printf("RESUBSCRIBE: %p\n%s\n",r->_origin,qUtf8Printable(r->toJson(0,true,true)));
528  }
529  }
530 
531  if (!r->_isCallback)
532  issueResponse(r);
533 
534  // need to submit this after the response, because otherwise it
535  // will not have a _sourcePathMap entry yet.
536  if (willIssueMounted)
537  issueMounted(issueMountedPath);
538  }
539  else
540  VFS::WARN( QString("Received a message with an unknown id: %1. Ignoring.").arg(id), 0, className() );
541 }
542 
551 {
552  #ifdef SHOW_JSON
553  printf("%s sends: %s\n",qUtf8Printable(className()),qUtf8Printable(message));
554  #endif
555 
556  #ifdef COMPRESS_TCP_MOUNT
557  message = qCompress(message);
558  #endif
559 
560  writeMessage(message);
561 }
562 
573 {
574  //printf("UNSUBSCRIBE ALL\n");
575 
576  //send an unsubscribe request to the connected client for each matching subscription
577  if (_mounted)
578  {
579  QMutexLocker l(&_lock);
580 
581  int c;
582 
583  QMutableMapIterator<QString, VFS_subscriptionOrigin > ito(_subscribers);
584  while (ito.hasNext())
585  {
586  ito.next();
587 
588  QMutableMapIterator<QString, VFS_subscriptionCounter > it(ito.value());
589  while (it.hasNext())
590  {
591  it.next();
592 
593  if (it.value().contains(subscriber))
594  c=it.value()[subscriber];
595  else
596  c = 0;
597 
598  if (c)
599  {
600  QJsonObject m;
601  m["unsubscriptions"] = c;
602  VFS_request *r = createRequest(VFS_request::unsubscribe,ito.key(),className(),QJsonDocument(),m);
603  executeRequest(r);
604  VFS::LOG( QString("unsubscribeAll removed '%1' %2 (%3 remote)").arg(ito.key()).arg(className()).arg(c), 9 );
605  //printf( "%s [[%s]]\n", qUtf8Printable( QString("unsubscribeAll removed '%1' %2 (%3 remote)").arg(ito.key()).arg(className()).arg(c) ), qUtf8Printable(ito.key()) );
606  }
607  }
608  }
609  }
610 
611  VFS_tcp_client::unsubscribeAll(subscriber);
612 }
613 
614 
623 {
624  //return;
625 
626  QMutexLocker l(&_lock);
627 
628  if (_subscribers.count())
629  VFS::LOG( QString("Refreshing subscriptions..."), 8, className() );
630  else
631  return;
632 
633  VFS_subscriptionType::iterator it = _subscribers.begin();
634  VFS_subscriptionOrigin::iterator ito;
635 
636  QString path;
639 
640  while (it!=_subscribers.end())
641  {
642  path = it.key();
643  o = it.value();
644 
645  ito = o.begin();
646  while (ito!=o.end())
647  {
648  c = ito.value();
649 
650  foreach(VFS_node *n,c.keys())
651  {
652  if (__isNode(n))
653  {
654  int count = c[n];
655 
657  r->_origin = n;
658  r->_originPath = ito.key();
660  r->_prefixPath = _path.split("/");
661  r->_metadata["subscriptions"] = count;
662  r->_metadata["resubscription"] = true;
663 
664  executeRequest(r);
665  //issueRequest(r);
666 
667  VFS::LOG( QString("(re)subscribing to '%1' (%2)\n").arg(path).arg(count), 8, className() );
668  }
669  else
670  VFS::WARN( "Skipping resubscribe on non-existent node\n" );
671  }
672 
673  ito++;
674  }
675 
676  it++;
677  }
678 }
679 
680 
688 {
689  //return;
690 
691  VFS_request *r;
692 
693  if (!_unmountedRequests.isEmpty())
694  {
695  VFS::LOG( QString("Sending unmounted requests..."), 9, className() );
696  while (_unmountedRequests.length())
697  {
698  r = _unmountedRequests.takeFirst();
699 
700  if (__isNode(r->_origin))
701  { //r->_dontDelete = false;
702  issueRequest(this,r);
703  }
704  else
705  { VFS::WARN(QString("Skipping request for non-node 0x%1").arg((quintptr)r->_origin, QT_POINTER_SIZE * 2, 16, QChar('0')),9,className());
706  delete r;
707  }
708  }
709  }
710 }
711 
712 
720 {
721  //printf("ISSUED UNMOUNTED\n");
722 
723  QMutexLocker l(&_lock);
724 
725  QJsonObject d;
726  d["mounted"] = false;
727 
728  VFS_subscriptionType::iterator it = _subscribers.begin();
729  VFS_subscriptionOrigin::iterator ito;
730 
731  QString path;
733 
734  while (it!=_subscribers.end())
735  {
736  path = it.key();
737 
738  VFS_request *r = createRequest(VFS_request::diff,path,className(),QJsonDocument(d));
739  emit diff(this,r);
740  delete r;
741 
742  it++;
743  }
744 }
745 
746 
754  {
755  //printf("ISSUED MOUNTED: %s\n",qUtf8Printable(path));
756 
757  QJsonObject d;
758  d["mounted"] = true;
759 
760  VFS_request *r = createRequest(VFS_request::diff,path,className(),QJsonDocument(d));
761  emit diff(this,r);
762  delete r;
763  }
764 
765 
773 {
774  postID s = _currentID;
775 
776  //FIXME : this increment is only for debugging... it should not be here... it may be better to use UUIDs in general, as they may debug more easily
777  //_currentID++;
778 
779  while (_requests.contains(_currentID))
780  {
781  //_currentID = rand(); //for debugging
782  //continue; //for debugging
783 
784  _currentID++;
785  if (_currentID > POST_ID_MAX)
787 
788  if (_currentID == s)
789  {
790  VFS::ERROR( QString("Could not find available id for request. Aborting."), 0, className() );
791  exit(3);
792  }
793  }
794 
795  return _currentID;
796 }
797 
798 
807 {
808  Q_UNUSED(r)
809 
810  return this;
811 }
812 
813 
820 {
821  return VFS_icons::get("unknown");
822 }
823 
824 
831 {
832  QMutexLocker l(&_lock);
833 
834  return _mounted;
835 }
836 
837 
844 {
845  QMutexLocker l(&_lock);
846 
847  return _path;
848 }
849 
850 
quint16 postID
Definition: VFS_node.h:24
#define POST_ID_CODE_DIRECTORY
Definition: VFS_node.h:20
#define POST_ID_START
Definition: VFS_node.h:21
#define POST_ID_SESSION_DATA
Definition: VFS_node.h:18
#define POST_ID_MAX
Definition: VFS_node.h:22
#define POST_ID_PING
Definition: VFS_node.h:17
#define POST_ID_DIFF
Definition: VFS_node.h:19
QMap< VFS_node *, qint32 > VFS_subscriptionCounter
Definition: VFS_node.h:29
QMap< QString, VFS_subscriptionCounter > VFS_subscriptionOrigin
Definition: VFS_node.h:35
#define VFS_TCP_MOUNT_PING_TIME_MS
Definition: VFS_tcp_mount.h:10
static char * get(QString which="")
Fetch an icon from the library.
Definition: VFS_icons.cpp:34
VFS_node is the base class from which all other VFS_node classes derive.
Definition: VFS_node.h:143
virtual void executeRequest(VFS_request *t)
Based on the VFS_request::requestType, execute the function associated with an operation.
Definition: VFS_node.cpp:1809
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.
Definition: VFS_node.cpp:1913
virtual void issueResponse(VFS_request *t)
Once a request has been completed, issue a response.
Definition: VFS_node.cpp:1981
virtual void unsubscribeAll(VFS_node *n)
Remove all references to a subscriber from this node.
Definition: VFS_node.cpp:1336
virtual void issueRequest(VFS_request *t)
A convenience function.
Definition: VFS_node.cpp:1933
static bool __isNode(VFS_node *)
Check to see if a node is in the global registry.
Definition: VFS_node.cpp:588
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.
Definition: VFS_node.cpp:2039
VFS_subscriptionType _subscribers
This node's subscribers. These subscribers will receive diff notifications.
Definition: VFS_node.h:180
QMutex _lock
A recursive mutex that is local to this node.
Definition: VFS_node.h:178
virtual void applyDiff(VFS_request *r)
Apply a diff received via subscription.
Definition: VFS_node.cpp:1463
virtual void unsubscribe(VFS_request *r)
Remove an entry from this node's _subscription list.
Definition: VFS_node.cpp:1263
The base class for all requests between nodes.
Definition: VFS_node.h:54
static const char * requestTypeStrings[]
A printable string for each request type.
Definition: VFS_node.h:127
@ diff
send a diff (7)
Definition: VFS_node.h:71
@ report
provide node report, for debugging (12)
Definition: VFS_node.h:76
@ unsubscribe
unsubscribe from a path (10)
Definition: VFS_node.h:74
@ codeDirectory
request a listing of code served by a node (16)
Definition: VFS_node.h:80
@ subscribe
subscribe to a path (9)
Definition: VFS_node.h:73
@ submit
apply a diff (8)
Definition: VFS_node.h:72
VFS_node * _origin
the origin of the request
Definition: VFS_node.h:89
requestType _requestType
the action this request is performing or requesting
Definition: VFS_node.h:87
QString _initialPath
the target path when the request was made (relative to the responder)
Definition: VFS_node.h:93
QStringList _prefixPath
the prefix elements found while searching for the target
Definition: VFS_node.h:94
QString _user
who initiated this request, mostly for logging
Definition: VFS_node.h:106
virtual void fromJsonObject(QJsonObject json, bool includeInitialPath=false)
Deserialize a JSON string into a VFS_request.
Definition: VFS_node.cpp:466
QString _path
the target path remnant... the remaining path element once the request has found its target
Definition: VFS_node.h:95
bool _isCallback
whether or not to issue a response (IE, another request is chained to this request,...
Definition: VFS_node.h:98
QString _originPath
the subpath of the origin node
Definition: VFS_node.h:90
QList< notifyException > _notifyExceptions
a list of nodes not to send responses to for this transaction. For instance if a node submits to a no...
Definition: VFS_node.h:110
bool _success
if the request was successfully completed
Definition: VFS_node.h:107
QJsonDocument _data
the request payload
Definition: VFS_node.h:102
virtual QByteArray toJson(postID id=0, bool ignoreSuccess=false, bool includeInitialPath=false)
Serialize this request.
Definition: VFS_node.cpp:415
QJsonObject _metadata
the request payload
Definition: VFS_node.h:101
The VFS_session object represents a single session.
Definition: VFS_session.h:14
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.
bool _ssl
Use ssl?
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.
Definition: VFS_tcp_mount.h:34
void attemptConnection()
DOCME.
static QList< VFS_tcp_mount * > _mounts
The list of existing mounts.
Definition: VFS_tcp_mount.h:54
virtual void stopPing()
DOCME.
QTimer _ping
The ping timer object.
Definition: VFS_tcp_mount.h:51
void sendUnmountedRequests()
DOCME.
postID _currentID
The current VFS_request_id.
Definition: VFS_tcp_mount.h:39
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.
Definition: VFS_tcp_mount.h:36
bool isMounted()
Return the state of _mounted.
virtual void startPing()
DOCME.
QString _name
The name of this node for logging purposes.
Definition: VFS_tcp_mount.h:33
bool _mounted
Is this mounted?
Definition: VFS_tcp_mount.h:37
virtual void sendPing()
DOCME.
void issueMounted(QString path)
VFS_tcp_mount::issueMounted.
QMap< postID, VFS_request * > _requests
Outstanding VFS_requests.
Definition: VFS_tcp_mount.h:40
virtual ~VFS_tcp_mount()
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.
Definition: VFS_tcp_mount.h:53
virtual void executeRequest(VFS_request *r)
DOCME.
VFS_tcp_mount_directory _codeDirectory
The directory of code available when mounted.
Definition: VFS_tcp_mount.h:49
QList< VFS_request * > _unmountedRequests
Requests to submit when re-mounted.
Definition: VFS_tcp_mount.h:43
int _attemptInterval
The interval to attempt (re)connections.
Definition: VFS_tcp_mount.h:35
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.
void init()
DOCME.
static void LOG(QString message, int level=0, QString user="server")
Send a message to the VFS::_messages VFS_stream.
Definition: VFS.cpp:209
static void ERROR(QString message, int level=0, QString user="server")
Send a message to the VFS::_errors VFS_stream.
Definition: VFS.cpp:307
static void WARN(QString message, int level=0, QString user="server")
Send a message to the VFS::_warnings VFS_stream.
Definition: VFS.cpp:258
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.
Definition: rutils.cpp:32