GitHub - socketio/socket.io-deno: Socket.IO server for Deno (original) (raw)
Socket.IO server for Deno
An implementation of the Socket.IO protocol for Deno.
Table of content:
Usage
import { Server } from "https://deno.land/x/socket_io@0.2.1/mod.ts";
const io = new Server();
io.on("connection", (socket) => {
console.log(socket ${socket.id} connected
);
socket.emit("hello", "world");
socket.on("disconnect", (reason) => {
console.log(socket <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>s</mi><mi>o</mi><mi>c</mi><mi>k</mi><mi>e</mi><mi>t</mi><mi mathvariant="normal">.</mi><mi>i</mi><mi>d</mi></mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>c</mi><mi>o</mi><mi>n</mi><mi>n</mi><mi>e</mi><mi>c</mi><mi>t</mi><mi>e</mi><mi>d</mi><mi>d</mi><mi>u</mi><mi>e</mi><mi>t</mi><mi>o</mi></mrow><annotation encoding="application/x-tex">{socket.id} disconnected due to </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord"><span class="mord mathnormal">soc</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span></span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">sco</span><span class="mord mathnormal">nn</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">dd</span><span class="mord mathnormal">u</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span></span></span></span>{reason}
);
});
});
Deno.serve({ handler: io.handler(), port: 3000, });
And then run with:
$ deno run --allow-net index.ts
Like the Node.js server, you can also provide types for the events sent between the server and the clients:
interface ServerToClientEvents { noArg: () => void; basicEmit: (a: number, b: string, c: Buffer) => void; withAck: (d: string, callback: (e: number) => void) => void; }
interface ClientToServerEvents { hello: () => void; }
interface InterServerEvents { ping: () => void; }
interface SocketData { user_id: string; }
const io = new Server< ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData
();
With oak
You need to use the .handle()method:
import { Server } from "https://deno.land/x/socket_io@0.2.0/mod.ts"; import { Application } from "https://deno.land/x/oak@14.2.0/mod.ts";
const app = new Application();
app.use((ctx) => { ctx.response.body = "Hello World!"; });
const io = new Server();
io.on("connection", (socket) => {
console.log(socket ${socket.id} connected
);
socket.emit("hello", "world");
socket.on("disconnect", (reason) => {
console.log(socket <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>s</mi><mi>o</mi><mi>c</mi><mi>k</mi><mi>e</mi><mi>t</mi><mi mathvariant="normal">.</mi><mi>i</mi><mi>d</mi></mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>c</mi><mi>o</mi><mi>n</mi><mi>n</mi><mi>e</mi><mi>c</mi><mi>t</mi><mi>e</mi><mi>d</mi><mi>d</mi><mi>u</mi><mi>e</mi><mi>t</mi><mi>o</mi></mrow><annotation encoding="application/x-tex">{socket.id} disconnected due to </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord"><span class="mord mathnormal">soc</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span></span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">sco</span><span class="mord mathnormal">nn</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">dd</span><span class="mord mathnormal">u</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span></span></span></span>{reason}
);
});
});
const handler = io.handler(async (req) => { return await app.handle(req) || new Response(null, { status: 404 }); });
Deno.serve({ handler, port: 3000, });
Options
path
Default value: /socket.io/
It is the name of the path that is captured on the server side.
Caution! The server and the client values must match (unless you are using a path-rewriting proxy in between).
Example:
const io = new Server(httpServer, { path: "/my-custom-path/", });
connectTimeout
Default value: 45000
The number of ms before disconnecting a client that has not successfully joined a namespace.
pingTimeout
Default value: 20000
This value is used in the heartbeat mechanism, which periodically checks if the connection is still alive between the server and the client.
The server sends a ping, and if the client does not answer with a pong withinpingTimeout
ms, the server considers that the connection is closed.
Similarly, if the client does not receive a ping from the server withinpingInterval + pingTimeout
ms, the client also considers that the connection is closed.
pingInterval
Default value: 25000
See pingTimeout for more explanation.
upgradeTimeout
Default value: 10000
This is the delay in milliseconds before an uncompleted transport upgrade is cancelled.
maxHttpBufferSize
Default value: 1e6
(1 MB)
This defines how many bytes a single message can be, before closing the socket. You may increase or decrease this value depending on your needs.
allowRequest
Default value: -
A function that receives a given handshake or upgrade request as its first parameter, and can decide whether to continue or not.
Example:
const io = new Server({ allowRequest: (req, connInfo) => { return Promise.reject("thou shall not pass"); }, });
cors
Default value: -
A set of options related toCross-Origin Resource Sharing(CORS).
Example:
const io = new Server({ cors: { origin: ["https://example.com"], allowedHeaders: ["my-header"], credentials: true, }, });
editHandshakeHeaders
Default value: -
A function that allows to edit the response headers of the handshake request.
Example:
const io = new Server({ editHandshakeHeaders: (responseHeaders, req, connInfo) => { responseHeaders.set("set-cookie", "sid=1234"); }, });
editResponseHeaders
Default value: -
A function that allows to edit the response headers of all requests.
Example:
const io = new Server({ editResponseHeaders: (responseHeaders, req, connInfo) => { responseHeaders.set("my-header", "abcd"); }, });
Logs
The library relies on the standard log
module, so you can display the internal logs of the Socket.IO server with:
import * as log from "https://deno.land/std@0.166.0/log/mod.ts";
await log.setup({ handlers: { console: new log.handlers.ConsoleHandler("DEBUG"), }, loggers: { "socket.io": { level: "DEBUG", handlers: ["console"], }, "engine.io": { level: "DEBUG", handlers: ["console"], }, }, });
Adapters
Custom adapters can be used to broadcast packets between several Socket.IO servers.
Redis adapter
Documentation: https://socket.io/docs/v4/redis-adapter/
import { createRedisAdapter, createRedisClient, Server, } from "https://deno.land/x/socket_io@0.2.0/mod.ts";
const [pubClient, subClient] = await Promise.all([ createRedisClient({ hostname: "localhost", }), createRedisClient({ hostname: "localhost", }), ]);
const io = new Server({ adapter: createRedisAdapter(pubClient, subClient), });
Deno.serve({ handler: io.handler(), port: 3000, });