-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add HTTP long-polling implementation based on fetch()
- Loading branch information
1 parent
fa47916
commit 92a4441
Showing
11 changed files
with
497 additions
and
336 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
import { Polling } from "./polling.js"; | ||
import { XHR } from "./polling-xhr.js"; | ||
import { WS } from "./websocket.js"; | ||
import { WT } from "./webtransport.js"; | ||
|
||
export const transports = { | ||
websocket: WS, | ||
webtransport: WT, | ||
polling: Polling, | ||
polling: XHR, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { Polling } from "./polling.js"; | ||
import { CookieJar, createCookieJar } from "./xmlhttprequest.js"; | ||
|
||
/** | ||
* HTTP long-polling based on `fetch()` | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/fetch | ||
*/ | ||
export class Fetch extends Polling { | ||
private readonly cookieJar?: CookieJar; | ||
|
||
constructor(opts) { | ||
super(opts); | ||
|
||
if (this.opts.withCredentials) { | ||
this.cookieJar = createCookieJar(); | ||
} | ||
} | ||
|
||
override async doPoll() { | ||
try { | ||
const res = await this._fetch(); | ||
|
||
if (!res.ok) { | ||
return this.onError("fetch read error", res.status, res); | ||
} | ||
|
||
const data = await res.text(); | ||
this.onData(data); | ||
} catch (e) { | ||
this.onError("fetch read error", e); | ||
} | ||
} | ||
|
||
override async doWrite(data: string, callback: () => void) { | ||
try { | ||
const res = await this._fetch(data); | ||
|
||
if (!res.ok) { | ||
return this.onError("fetch write error", res.status, res); | ||
} | ||
|
||
callback(); | ||
} catch (e) { | ||
this.onError("fetch write error", e); | ||
} | ||
} | ||
|
||
private async _fetch(data?: string) { | ||
const isPost = data !== undefined; | ||
const headers = new Headers(this.opts.extraHeaders); | ||
|
||
if (isPost) { | ||
headers.set("content-type", "text/plain;charset=UTF-8"); | ||
} | ||
|
||
this.cookieJar?.appendCookies(headers); | ||
|
||
const res = await fetch(this.uri(), { | ||
method: isPost ? "POST" : "GET", | ||
body: isPost ? data : null, | ||
headers, | ||
credentials: this.opts.withCredentials ? "include" : "omit", | ||
}); | ||
|
||
if (this.cookieJar) { | ||
// @ts-ignore getSetCookie() was added in Node.js v19.7.0 | ||
this.cookieJar.parseCookies(res.headers.getSetCookie()); | ||
} | ||
|
||
return res; | ||
} | ||
} |
Oops, something went wrong.