_sendRequest(ctx, resolve, reject) {
		const isStream =
			ctx.params &&
			ctx.params.readable === true &&
			typeof ctx.params.on === "function" &&
			typeof ctx.params.pipe === "function";

		const request = {
			action: ctx.action,
			nodeID: ctx.nodeID,
			ctx,
			resolve,
			reject,
			stream: isStream // ???
		};

		const payload = {
			id: ctx.id,
			action: ctx.action.name,
			params: isStream ? null : ctx.params,
			meta: ctx.meta,
			timeout: ctx.options.timeout,
			level: ctx.level,
			tracing: ctx.tracing,
			parentID: ctx.parentID,
			requestID: ctx.requestID,
			caller: ctx.caller,
			stream: isStream
		};

		if (payload.stream) {
			if (
				ctx.params.readableObjectMode === true ||
				(ctx.params._readableState && ctx.params._readableState.objectMode === true)
			) {
				payload.meta = payload.meta || {};
				payload.meta["$streamObjectMode"] = true;
			}
			payload.seq = 0;
		}

		const packet = new Packet(P.PACKET_REQUEST, ctx.nodeID, payload);

		const nodeName = ctx.nodeID ? `'${ctx.nodeID}'` : "someone";
		const requestID = ctx.requestID ? "with requestID '" + ctx.requestID + "' " : "";
		this.logger.debug(`=> Send '${ctx.action.name}' request ${requestID}to ${nodeName} node.`);

		const publishCatch = /* istanbul ignore next */ err => {
			this.logger.error(
				`Unable to send '${ctx.action.name}' request ${requestID}to ${nodeName} node.`,
				err
			);

			this.broker.broadcastLocal("$transit.error", {
				error: err,
				module: "transit",
				type: C.FAILED_SEND_REQUEST_PACKET
			});
		};

		// Add to pendings
		this.pendingRequests.set(ctx.id, request);

		if (request.stream) {
			const pass = request.ctx.params;

			pass.on("moleculer-timeout-middleware", timeout => {
				this._destroyStreamIfPossible(
					pass,
					`Request stream ${ctx.id} have been closed by timeout ${timeout} ms`
				);
			});
		}

		// Publish request
		return this.publish(packet)
			.then(() => {
				if (isStream) {
					// Skip to send ctx.meta with chunks because it doesn't appear on the remote side.
					payload.meta = {};
					// Still send information about objectMode in case of packets are received in wrong order
					if (
						ctx.params.readableObjectMode === true ||
						(ctx.params._readableState && ctx.params._readableState.objectMode === true)
					) {
						payload.meta["$streamObjectMode"] = true;
					}

					const stream = ctx.params;
					stream.on("data", chunk => {
						stream.pause();
						const chunks = [];
						if (
							chunk instanceof Buffer &&
							this.opts.maxChunkSize > 0 &&
							chunk.length > this.opts.maxChunkSize
						) {
							let len = chunk.length;
							let i = 0;
							while (i < len) {
								chunks.push(chunk.slice(i, (i += this.opts.maxChunkSize)));
							}
						} else {
							chunks.push(chunk);
						}

						return this.Promise.all(
							chunks.map(ch => {
								const copy = Object.assign({}, payload);
								copy.seq = ++payload.seq;
								copy.stream = true;
								copy.params = ch;

								this.logger.debug(
									`=> Send stream chunk ${requestID}to ${nodeName} node. Seq: ${copy.seq}`
								);

								return this.publish(new Packet(P.PACKET_REQUEST, ctx.nodeID, copy));
							})
						)
							.then(() => stream.resume())
							.catch(publishCatch);
					});

					stream.on("end", () => {
						const copy = Object.assign({}, payload);
						copy.seq = ++payload.seq;
						copy.params = null;
						copy.stream = false;

						this.logger.debug(
							`=> Send stream closing ${requestID}to ${nodeName} node. Seq: ${copy.seq}`
						);

						return this.publish(new Packet(P.PACKET_REQUEST, ctx.nodeID, copy)).catch(
							publishCatch
						);
					});

					stream.on("error", err => {
						const copy = Object.assign({}, payload);
						copy.seq = ++payload.seq;
						copy.stream = false;
						copy.meta["$streamError"] = this._createPayloadErrorField(err, payload);
						copy.params = null;

						this.logger.debug(
							`=> Send stream error ${requestID}to ${nodeName} node.`,
							copy.meta["$streamError"]
						);

						return this.publish(new Packet(P.PACKET_REQUEST, ctx.nodeID, copy)).catch(
							publishCatch
						);
					});
				}
			})
			.catch(err => {
				publishCatch(err);
				reject(err);
			});
	}
Send a remote request

@param {<Context>} ctx      Context of request
@param {Function} resolve   Resolve of Promise
@param {Function} reject    Reject of Promise

@memberof Transit