constructor(localNode, remoteNodeId, remoteNodeIP) {
    // not to be confused with remote nodes
    this.localNode = localNode;

    this.remoteNodeIP = remoteNodeIP;
    this.remoteNodeAddress = `tcp://${remoteNodeIP}:${this.localNode.config.ports.sync}`;
    this.remoteNodeId = remoteNodeId;
    // Used in debug mode when the node might be slower
    this.remoteNodeEvictionPrevented = false;
    this.socket = null;
    this.protoroot = null;

    // keeps track of received message ids from the remote node
    this.lastMessageId = new Long(0, 0, true);

    // A subscriber starts in the BUFFERING state, meaning it stores incoming
    // sync messages without processing them, until it enters the SANE state
    // This delays applying sync messages while the local node initializes
    this.state = stateEnum.BUFFERING;
    this.buffer = [];

    // keeps track of the remote node heartbeats, and evicts it if no
    // heartbeats have been received after some time
    this.heartbeatTimer = null;
    this.lastHeartbeat = Date.now();
    this.heartbeatDelay = this.localNode.heartbeatDelay * 1.5;

    // Messages handlers (quick translation between a topic name and its
    // associated handler)
    this.handlers = Object.freeze({
      AddCollection: this.handleCollectionAddition,
      AddIndex: this.handleIndexAddition,
      ClusterWideEvent: this.handleClusterWideEvent,
      DocumentNotification: this.handleDocumentNotification,
      DumpRequest: this.handleDumpRequest,
      Heartbeat: this.handleHeartbeat,
      InvalidateProfile: this.handleProfileInvalidation,
      InvalidateRole: this.handleRoleInvalidation,
      NewAuthStrategy: this.handleNewAuthStrategy,
      NewRealtimeRoom: this.handleNewRealtimeRoom,
      NodeEvicted: this.handleNodeEviction,
      NodePreventEviction: this.handleNodePreventEviction,
      NodeShutdown: this.handleNodeShutdown,
      RefreshIndexCache: this.handleRefreshIndexCache,
      RefreshValidators: this.handleRefreshValidators,
      RemoveAuthStrategy: this.handleAuthStrategyRemoval,
      RemoveCollection: this.handleCollectionRemoval,
      RemoveIndexes: this.handleIndexesRemoval,
      RemoveRealtimeRoom: this.handleRealtimeRoomRemoval,
      ResetSecurity: this.handleResetSecurity,
      Shutdown: this.handleShutdown,
      Subscription: this.handleSubscription,
      Unsubscription: this.handleUnsubscription,
      UserNotification: this.handleUserNotification,
    });
  }
@constructor
@param {ClusterNode} localNode
@param {string} remoteNodeId - Remote node unique ID
@param {string} remoteNodeIP - address of the distant node