UNPKG

@microsoft/signalr

Version:
107 lines 4.95 kB
"use strict"; // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. Object.defineProperty(exports, "__esModule", { value: true }); exports.ServerSentEventsTransport = void 0; const ILogger_1 = require("./ILogger"); const ITransport_1 = require("./ITransport"); const Utils_1 = require("./Utils"); /** @private */ class ServerSentEventsTransport { constructor(httpClient, accessToken, logger, options) { this._httpClient = httpClient; this._accessToken = accessToken; this._logger = logger; this._options = options; this.onreceive = null; this.onclose = null; } async connect(url, transferFormat) { Utils_1.Arg.isRequired(url, "url"); Utils_1.Arg.isRequired(transferFormat, "transferFormat"); Utils_1.Arg.isIn(transferFormat, ITransport_1.TransferFormat, "transferFormat"); this._logger.log(ILogger_1.LogLevel.Trace, "(SSE transport) Connecting."); // set url before accessTokenFactory because this._url is only for send and we set the auth header instead of the query string for send this._url = url; if (this._accessToken) { url += (url.indexOf("?") < 0 ? "?" : "&") + `access_token=${encodeURIComponent(this._accessToken)}`; } return new Promise((resolve, reject) => { let opened = false; if (transferFormat !== ITransport_1.TransferFormat.Text) { reject(new Error("The Server-Sent Events transport only supports the 'Text' transfer format")); return; } let eventSource; if (Utils_1.Platform.isBrowser || Utils_1.Platform.isWebWorker) { eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials }); } else { // Non-browser passes cookies via the dictionary const cookies = this._httpClient.getCookieString(url); const headers = {}; headers.Cookie = cookies; const [name, value] = (0, Utils_1.getUserAgentHeader)(); headers[name] = value; eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials, headers: { ...headers, ...this._options.headers } }); } try { eventSource.onmessage = (e) => { if (this.onreceive) { try { this._logger.log(ILogger_1.LogLevel.Trace, `(SSE transport) data received. ${(0, Utils_1.getDataDetail)(e.data, this._options.logMessageContent)}.`); this.onreceive(e.data); } catch (error) { this._close(error); return; } } }; // @ts-ignore: not using event on purpose eventSource.onerror = (e) => { // EventSource doesn't give any useful information about server side closes. if (opened) { this._close(); } else { reject(new Error("EventSource failed to connect. The connection could not be found on the server," + " either the connection ID is not present on the server, or a proxy is refusing/buffering the connection." + " If you have multiple servers check that sticky sessions are enabled.")); } }; eventSource.onopen = () => { this._logger.log(ILogger_1.LogLevel.Information, `SSE connected to ${this._url}`); this._eventSource = eventSource; opened = true; resolve(); }; } catch (e) { reject(e); return; } }); } async send(data) { if (!this._eventSource) { return Promise.reject(new Error("Cannot send until the transport is connected")); } return (0, Utils_1.sendMessage)(this._logger, "SSE", this._httpClient, this._url, data, this._options); } stop() { this._close(); return Promise.resolve(); } _close(e) { if (this._eventSource) { this._eventSource.close(); this._eventSource = undefined; if (this.onclose) { this.onclose(e); } } } } exports.ServerSentEventsTransport = ServerSentEventsTransport; //# sourceMappingURL=ServerSentEventsTransport.js.map