132 lines
No EOL
6.9 KiB
JavaScript
132 lines
No EOL
6.9 KiB
JavaScript
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.NamedPipeServer = void 0;
|
|
const namedPipeTransport_1 = require("./namedPipeTransport");
|
|
const payloadTransport_1 = require("../payloadTransport");
|
|
const protocolAdapter_1 = require("../protocolAdapter");
|
|
const payloads_1 = require("../payloads");
|
|
const createNodeServer_1 = require("../utilities/createNodeServer");
|
|
/**
|
|
* Streaming transport server implementation that uses named pipes for inter-process communication.
|
|
*/
|
|
class NamedPipeServer {
|
|
/**
|
|
* Creates a new instance of the [NamedPipeServer](xref:botframework-streaming.NamedPipeServer) class.
|
|
*
|
|
* @param baseName The named pipe to connect to.
|
|
* @param requestHandler Optional [RequestHandler](xref:botframework-streaming.RequestHandler) to process incoming messages received by this client.
|
|
* @param autoReconnect Deprecated: Automatic reconnection is the default behavior.
|
|
*/
|
|
constructor(baseName, requestHandler, autoReconnect) {
|
|
this.baseName = baseName;
|
|
this._sender = new payloadTransport_1.PayloadSender();
|
|
this._receiver = new payloadTransport_1.PayloadReceiver();
|
|
if (!baseName) {
|
|
throw new TypeError('NamedPipeServer: Missing baseName parameter');
|
|
}
|
|
if (autoReconnect != null) {
|
|
console.warn('NamedPipeServer: The autoReconnect parameter is deprecated');
|
|
}
|
|
this._sender = new payloadTransport_1.PayloadSender();
|
|
this._receiver = new payloadTransport_1.PayloadReceiver();
|
|
this._protocolAdapter = new protocolAdapter_1.ProtocolAdapter(requestHandler, new payloads_1.RequestManager(), this._sender, this._receiver);
|
|
}
|
|
/**
|
|
* Get connected status
|
|
*
|
|
* @returns true if currently connected.
|
|
*/
|
|
get isConnected() {
|
|
return this._receiver.isConnected && this._sender.isConnected;
|
|
}
|
|
/**
|
|
* Used to establish the connection used by this server and begin listening for incoming messages.
|
|
*
|
|
* @param onListen Optional callback that fires once when server is listening on both incoming and outgoing pipe
|
|
* @returns A promised string that will not resolve as long as the server is running.
|
|
*/
|
|
start(onListen) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const { PipePath, ServerIncomingPath, ServerOutgoingPath } = namedPipeTransport_1.NamedPipeTransport;
|
|
// The first promise resolves as soon as the server is listening. The second resolves when the server
|
|
// closes, or an error occurs. Wrapping with an array ensures the initial await only waits for the listening
|
|
// promise.
|
|
//
|
|
// We want to ensure we are listening to the servers in series so that, if two processes start at the same
|
|
// time, only one is able to listen on both the incoming and outgoing sockets.
|
|
const [incoming] = yield new Promise((resolveListening, rejectListening) => {
|
|
const server = (0, createNodeServer_1.createNodeServer)((socket) => {
|
|
if (this._receiver.isConnected) {
|
|
return;
|
|
}
|
|
this._receiver.connect(new namedPipeTransport_1.NamedPipeTransport(socket));
|
|
}).once('error', rejectListening);
|
|
this._incomingServer = server;
|
|
const isListening = new Promise((resolveClosed, rejectClosed) => {
|
|
// Only register rejection once the server is actually listening
|
|
server.once('listening', () => server.once('error', rejectClosed));
|
|
server.once('closed', resolveClosed);
|
|
});
|
|
server.once('listening', () => resolveListening([isListening]));
|
|
server.listen(PipePath + this.baseName + ServerIncomingPath);
|
|
});
|
|
// Now that we absolutely have the incoming socket, bind the outgoing socket as well
|
|
const [outgoing] = yield new Promise((resolveListening, rejectListening) => {
|
|
const server = (0, createNodeServer_1.createNodeServer)((socket) => {
|
|
if (this._sender.isConnected) {
|
|
return;
|
|
}
|
|
// Note: manually disconnect sender if client closes socket. This ensures that
|
|
// reconnections are allowed
|
|
this._sender.connect(new namedPipeTransport_1.NamedPipeTransport(socket));
|
|
socket.once('close', () => this._sender.disconnect());
|
|
}).once('error', rejectListening);
|
|
this._outgoingServer = server;
|
|
const isListening = new Promise((resolveClosed, rejectClosed) => {
|
|
// Only register rejection once the server is actually listening
|
|
server.once('listening', () => server.once('error', rejectClosed));
|
|
server.once('closed', resolveClosed);
|
|
});
|
|
server.once('listening', () => resolveListening([isListening]));
|
|
server.listen(PipePath + this.baseName + ServerOutgoingPath);
|
|
});
|
|
onListen === null || onListen === void 0 ? void 0 : onListen();
|
|
yield Promise.all([incoming, outgoing]);
|
|
return 'connected';
|
|
});
|
|
}
|
|
/**
|
|
* Allows for manually disconnecting the server.
|
|
*/
|
|
disconnect() {
|
|
var _a, _b;
|
|
this._receiver.disconnect();
|
|
(_a = this._incomingServer) === null || _a === void 0 ? void 0 : _a.close();
|
|
this._incomingServer = null;
|
|
this._sender.disconnect();
|
|
(_b = this._outgoingServer) === null || _b === void 0 ? void 0 : _b.close();
|
|
this._outgoingServer = null;
|
|
}
|
|
/**
|
|
* Task used to send data over this client connection.
|
|
*
|
|
* @param request The [StreamingRequest](xref:botframework-streaming.StreamingRequest) to send.
|
|
* @returns A promise for an instance of [IReceiveResponse](xref:botframework-streaming.IReceiveResponse) on completion of the send operation.
|
|
*/
|
|
send(request) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
return this._protocolAdapter.sendRequest(request);
|
|
});
|
|
}
|
|
}
|
|
exports.NamedPipeServer = NamedPipeServer;
|
|
//# sourceMappingURL=namedPipeServer.js.map
|