UNPKG

botframework-streaming

Version:

Streaming library for the Microsoft Bot Framework

138 lines 4.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NamedPipeTransport = void 0; /** * Named pipes based transport sender and receiver abstraction */ class NamedPipeTransport { /** * Creates a new instance of the [NamedPipeTransport](xref:botframework-streaming.NamedPipeTransport) class. * * @param socket The socket object to build this connection on. */ constructor(socket) { this.socket = socket; this._activeOffset = 0; this._activeReceiveCount = 0; this._queue = []; if (socket) { this.socket.on('data', (data) => { this.socketReceive(data); }); this.socket.on('close', () => { this.socketClose(); }); this.socket.on('error', (err) => { this.socketError(err); }); } } /** * Writes to the pipe and sends. * * @param buffer The buffer full of data to send out across the socket. * @returns A number indicating the length of the sent data if the data was successfully sent, otherwise 0. */ send(buffer) { if (this.socket && !this.socket.connecting && this.socket.writable) { this.socket.write(buffer); return buffer.length; } return 0; } /** * Returns `true` if currently connected. * * @returns `true` if the the transport is connected and ready to send data, `false` otherwise. */ get isConnected() { return !(!this.socket || this.socket.destroyed || this.socket.connecting); } /** * Closes the transport. */ close() { if (this.socket) { this.socket.end('end'); this.socket = null; } } /** * Receive from the transport into the buffer. * * @param count The maximum amount of bytes to write to the buffer. * @returns The buffer containing the data from the transport. */ receive(count) { if (this._activeReceiveResolve) { throw new Error('Cannot call receive more than once before it has returned.'); } this._activeReceiveCount = count; const promise = new Promise((resolve, reject) => { this._activeReceiveResolve = resolve; this._activeReceiveReject = reject; }); this.trySignalData(); return promise; } socketReceive(data) { if (this._queue && data && data.length > 0) { this._queue.push(data); this.trySignalData(); } } socketClose() { if (this._activeReceiveReject) { this._activeReceiveReject(new Error('Socket was closed.')); } this._active = null; this._activeOffset = 0; this._activeReceiveResolve = null; this._activeReceiveReject = null; this._activeReceiveCount = 0; this.socket = null; } socketError(err) { if (this._activeReceiveReject) { this._activeReceiveReject(err); } this.socketClose(); } trySignalData() { if (this._activeReceiveResolve) { if (!this._active && this._queue.length > 0) { this._active = this._queue.shift(); this._activeOffset = 0; } if (this._active) { if (this._activeOffset === 0 && this._active.length === this._activeReceiveCount) { // can send the entire _active buffer const buffer = this._active; this._active = null; this._activeReceiveResolve(buffer); } else { // create a new buffer and copy some of the contents into it const available = Math.min(this._activeReceiveCount, this._active.length - this._activeOffset); const buffer = Buffer.alloc(available); this._active.copy(buffer, 0, this._activeOffset, this._activeOffset + available); this._activeOffset += available; // if we used all of active, set it to undefined if (this._activeOffset >= this._active.length) { this._active = null; this._activeOffset = 0; } this._activeReceiveResolve(buffer); } this._activeReceiveCount = 0; this._activeReceiveReject = null; this._activeReceiveResolve = null; } } } } exports.NamedPipeTransport = NamedPipeTransport; NamedPipeTransport.PipePath = '\\\\.\\pipe\\'; NamedPipeTransport.ServerIncomingPath = '.incoming'; NamedPipeTransport.ServerOutgoingPath = '.outgoing'; //# sourceMappingURL=namedPipeTransport.js.map