@microsoft/signalr
Version:
ASP.NET Core SignalR Client
107 lines • 4.95 kB
JavaScript
"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