/
githubmirror
/
socket.io
Обзор
Документация
Войти
/
githubmirror
/
socket.io
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/socket.io-cluster-engine/test/in-memory.ts
366 строк
8 KB
Wang Guan
chore: use prettier v3 everywhere (#5169)
16 сен 2024, 09:43
Не верифицирован
16 сен 2024, 09:43
a1ccba3
Код
Авторство
О чём код?
import { EventEmitter } from "node:events"; import { createServer, Server } from "node:http"; import expect = require("expect.js"); import { WebSocket } from "ws"; import { ClusterEngine, type Message } from "../lib/engine"; import { type ServerOptions } from "engine.io"; import { url, handshake } from "./util"; class InMemoryEngine extends ClusterEngine { constructor( readonly eventBus: EventEmitter, opts?: ServerOptions, ) { super(opts); eventBus.on("message", (message) => this.onMessage(message)); } publishMessage(message: Message) { this.eventBus.emit("message", message); } } describe("in-memory", () => { let engine1: ClusterEngine, httpServer1: Server, engine2: ClusterEngine, httpServer2: Server, engine3: ClusterEngine, httpServer3: Server; beforeEach(() => { const eventBus = new EventEmitter(); httpServer1 = createServer(); engine1 = new InMemoryEngine(eventBus); engine1.attach(httpServer1); httpServer1.listen(3000); httpServer2 = createServer(); engine2 = new InMemoryEngine(eventBus); engine2.attach(httpServer2); httpServer2.listen(3001); httpServer3 = createServer(); engine3 = new InMemoryEngine(eventBus, { pingInterval: 50, }); engine3.attach(httpServer3); httpServer3.listen(3002); }); afterEach(() => { engine1.close(); engine2.close(); engine3.close(); httpServer1.close(); httpServer1.closeAllConnections(); httpServer2.close(); httpServer2.closeAllConnections(); httpServer3.close(); httpServer3.closeAllConnections(); }); it("should work (read)", (done) => { engine1.on("connection", (socket) => { socket.send("hello"); }); (async () => { const sid = await handshake(3000); const res = await fetch(url(3001, sid)); expect(res.status).to.eql(200); const body = await res.text(); expect(body).to.eql("4hello"); done(); })(); }); it("should work (read - deferred)", (done) => { engine1.on("connection", (socket) => { setTimeout(() => { socket.send("hello"); }, 200); }); (async () => { const sid = await handshake(3000); const res = await fetch(url(3001, sid)); expect(res.status).to.eql(200); const body = await res.text(); expect(body).to.eql("4hello"); done(); })(); }); it("should work (write)", (done) => { engine1.on("connection", (socket) => { socket.on("message", (data) => { expect(data).to.eql("hello"); done(); }); }); (async () => { const sid = await handshake(3000); const res = await fetch(url(3001, sid), { method: "POST", body: "4hello", }); expect(res.status).to.eql(200); })(); }); it("should work (write - multiple)", (done) => { engine1.on("connection", (socket) => { let packets = []; socket.on("message", (data) => { packets.push(data); if (packets.length === 6) { expect(packets).to.eql(["1", "2", "3", "4", "5", "6"]); done(); } }); }); (async () => { const sid = await handshake(3000); const res1 = await fetch(url(3001, sid), { method: "POST", body: "41\x1e42\x1e43", }); expect(res1.status).to.eql(200); const res2 = await fetch(url(3000, sid), { method: "POST", body: "44\x1e45", }); expect(res2.status).to.eql(200); const res3 = await fetch(url(3001, sid), { method: "POST", body: "46", }); expect(res3.status).to.eql(200); })(); }); it("should acquire read lock (different process)", (done) => { (async () => { const sid = await handshake(3000); const controller = new AbortController(); fetch(url(3000, sid), { signal: controller.signal, }); const res = await fetch(url(3001, sid)); expect(res.status).to.eql(400); controller.abort(); done(); })(); }); it("should acquire read lock (same process)", (done) => { (async () => { const sid = await handshake(3000); const controller = new AbortController(); fetch(url(3001, sid), { signal: controller.signal, }); const res = await fetch(url(3000, sid)); expect(res.status).to.eql(400); controller.abort(); done(); })(); }); it("should handle close from main process", (done) => { engine1.on("connection", (socket) => { setTimeout(() => { socket.close(); }, 100); }); (async () => { const sid = await handshake(3000); const res = await fetch(url(3001, sid)); expect(res.status).to.eql(200); const body = await res.text(); expect(body).to.eql("1"); done(); })(); }); it("should handle close from client", (done) => { engine1.on("connection", (socket) => { socket.on("close", (reason) => { expect(reason).to.eql("transport error"); done(); }); }); (async () => { const sid = await handshake(3000); const controller = new AbortController(); fetch(url(3001, sid), { signal: controller.signal, }); setTimeout(() => { controller.abort(); }, 100); })(); }); it("should ping/pong", function (done) { (async () => { const sid = await handshake(3002); for (let i = 0; i < 10; i++) { const port1 = [3000, 3001, 3002][i % 3]; const res1 = await fetch(url(port1, sid)); expect(res1.status).to.eql(200); const body1 = await res1.text(); expect(body1).to.eql("2"); const port2 = [3000, 3001, 3002][(i + 1) % 3]; const res2 = await fetch(url(port2, sid), { method: "POST", body: "3", }); expect(res2.status).to.eql(200); } // @ts-expect-error expect(engine1._requests.size).to.eql(0); // @ts-expect-error expect(engine2._requests.size).to.eql(0); // @ts-expect-error expect(engine3._requests.size).to.eql(0); // @ts-expect-error expect(engine1._remoteTransports.size).to.eql(0); // @ts-expect-error expect(engine2._remoteTransports.size).to.eql(0); // @ts-expect-error expect(engine3._remoteTransports.size).to.eql(0); done(); })(); }); it("should reject an invalid id", (done) => { (async () => { const res = await fetch(url(3001, "01234567890123456789")); expect(res.status).to.eql(400); done(); })(); }); it("should upgrade", (done) => { engine2.on("connection", (socket) => { socket.on("upgrade", () => { socket.send("hello"); }); socket.on("message", (val) => { expect(val).to.eql("hi"); socket.close(); done(); }); }); (async () => { const sid = await handshake(3000); const socket = new WebSocket( `ws://localhost:3001/engine.io/?EIO=4&transport=websocket&sid=${sid}`, ); socket.onopen = () => { socket.send("2probe"); }; let i = 0; socket.onmessage = ({ data }) => { switch (i++) { case 0: expect(data).to.eql("3probe"); socket.send("5"); break; case 1: expect(data).to.eql("4hello"); socket.send("4hi"); break; } }; })(); }); it("should upgrade and send buffered messages", (done) => { engine2.on("connection", (socket) => { socket.on("upgrade", () => { socket.send("hello"); }); socket.on("message", (val) => { expect(val).to.eql("hi"); socket.close(); done(); }); }); (async () => { const sid = await handshake(3000); const res = await fetch(url(3001, sid), { method: "POST", body: "4hi", }); expect(res.status).to.eql(200); const socket = new WebSocket( `ws://localhost:3001/engine.io/?EIO=4&transport=websocket&sid=${sid}`, ); socket.onopen = () => { socket.send("2probe"); }; let i = 0; socket.onmessage = ({ data }) => { switch (i++) { case 0: expect(data).to.eql("3probe"); socket.send("5"); break; case 1: expect(data).to.eql("4hello"); break; } }; })(); }); });