feat: auto generated peer id

This commit is contained in:
Pooya Parsa
2024-02-26 14:07:35 +01:00
parent cbeb47218e
commit a3b61f535a
11 changed files with 56 additions and 52 deletions

View File

@@ -17,9 +17,13 @@ Websocket [hooks](/guide/hooks) accept a peer instance as their first argument.
Send a message to the connected client
### `peer.addr`
The peer address (might be `undefined`)
### `peer.id`
The peer address or unique id (might be `undefined`)
A unique id assigned to the peer.
### `peer.readyState`

View File

@@ -10,13 +10,13 @@ export const websocket = {
hooks: defineHooks({
open(peer) {
console.log("[ws] open", peer);
peer.send({ user: "system", message: `Welcome ${peer}!` });
peer.send({ user: "server", message: `Welcome ${peer}!` });
},
message(peer, message) {
console.log("[ws] message", peer, message);
if (message.text().includes("ping")) {
peer.send({ user: "system", message: "pong" });
peer.send({ user: "server", message: "pong" });
} else {
peer.send({ user: peer.toString(), message: message.toString() });
}

View File

@@ -64,12 +64,12 @@
const isSecure = location.protocol === "https:";
const url = (isSecure ? "wss://" : "ws://") + location.host + "/_ws";
if (ws) {
log("system", "Closing previous connection before reconnecting...");
log("ws", "Closing previous connection before reconnecting...");
ws.close();
clear();
}
log("system", "Connecting to", url, "...");
log("ws", "Connecting to", url, "...");
ws = new WebSocket(url);
ws.addEventListener("message", (event) => {
@@ -83,7 +83,7 @@
});
await new Promise((resolve) => ws.addEventListener("open", resolve));
log("system", "Connected!");
log("ws", "Connected!");
};
const clear = () => {
@@ -100,7 +100,7 @@
};
const ping = () => {
log("you", "Sending ping");
log("ws", "Sending ping");
ws.send("ping");
};
@@ -114,7 +114,6 @@
}).mount();
await connect();
ping();
</script>
</head>
<body class="h-screen flex flex-col justify-between">
@@ -126,7 +125,7 @@
<p class="text-gray-500 mb-1 text-xs ml-10">{{ message.user }}</p>
<div class="flex items-center">
<img
:src="'https://www.gravatar.com/avatar/' + (message.user + rand) + '?s=512&d=monsterid'"
:src="'https://www.gravatar.com/avatar/' + encodeURIComponent(message.user + rand) + '?s=512&d=monsterid'"
alt="Avatar"
class="w-8 h-8 rounded-full"
/>

View File

@@ -65,12 +65,12 @@ export default /* html */ `
const isSecure = location.protocol === "https:";
const url = (isSecure ? "wss://" : "ws://") + location.host + "/_ws";
if (ws) {
log("system", "Closing previous connection before reconnecting...");
log("ws", "Closing previous connection before reconnecting...");
ws.close();
clear();
}
log("system", "Connecting to", url, "...");
log("ws", "Connecting to", url, "...");
ws = new WebSocket(url);
ws.addEventListener("message", (event) => {
@@ -84,7 +84,7 @@ export default /* html */ `
});
await new Promise((resolve) => ws.addEventListener("open", resolve));
log("system", "Connected!");
log("ws", "Connected!");
};
const clear = () => {
@@ -101,7 +101,7 @@ export default /* html */ `
};
const ping = () => {
log("you", "Sending ping");
log("ws", "Sending ping");
ws.send("ping");
};
@@ -115,7 +115,6 @@ export default /* html */ `
}).mount();
await connect();
ping();
</script>
</head>
<body class="h-screen flex flex-col justify-between">
@@ -127,7 +126,7 @@ export default /* html */ `
<p class="text-gray-500 mb-1 text-xs ml-10">{{ message.user }}</p>
<div class="flex items-center">
<img
:src="'https://www.gravatar.com/avatar/' + (message.user + rand) + '?s=512&d=monsterid'"
:src="'https://www.gravatar.com/avatar/' + encodeURIComponent(message.user + rand) + '?s=512&d=monsterid'"
alt="Avatar"
class="w-8 h-8 rounded-full"
/>
@@ -187,5 +186,5 @@ export default /* html */ `
</div>
</main>
</body>
</html>
</html>\
`.trim();

View File

@@ -8,19 +8,16 @@ export function createDemo<T extends Adapter<any, any>>(
options?: Parameters<T>[0],
): ReturnType<T> {
const hooks = defineHooks({
$(name, peer, ...args) {
console.log(
`$ ${peer} ${name} (${args.map((arg) => stringify(arg)).join(", ")})`,
);
},
open(peer) {
peer.send({ user: "system", message: `Welcome to the server ${peer}!` });
console.log(`[ws] open ${peer}`);
peer.send({ user: "server", message: `Welcome to the server ${peer}!` });
peer.subscribe("chat");
peer.publish("chat", { user: "system", message: `${peer} joined!` });
peer.publish("chat", { user: "server", message: `${peer} joined!` });
},
message(peer, message) {
console.log(`[ws] message ${peer} ${message.text()}`);
if (message.text() === "ping") {
peer.send({ user: "system", message: "pong" });
peer.send({ user: "server", message: "pong" });
} else {
const _message = {
user: peer.toString(),
@@ -31,6 +28,7 @@ export function createDemo<T extends Adapter<any, any>>(
}
},
upgrade(req) {
console.log("[ws] upgrade", req.url);
return {
headers: {
"x-powered-by": "cross-ws",
@@ -38,28 +36,18 @@ export function createDemo<T extends Adapter<any, any>>(
},
};
},
});
const resolve: ResolveHooks = (info) => {
return {
open: (peer) => {
peer.send({
message: {
info: {
url: info.url,
headers:
info.headers && Object.fromEntries(new Headers(info.headers)),
close(peer, details) {
console.log(`[ws] close ${peer}`, details);
},
error(peer, error) {
console.log(`[ws] error ${peer}`, error);
},
});
},
};
};
return adapter({
...options,
hooks,
resolve,
// resolve,
});
}

View File

@@ -81,7 +81,7 @@ export default defineWebSocketAdapter<BunAdapter, BunOptions>(
class BunPeer extends Peer<{
bun: { ws: ServerWebSocket<ContextData> };
}> {
get id() {
get addr() {
let addr = this.ctx.bun.ws.remoteAddress;
if (addr.includes(":")) {
addr = `[${addr}]`;

View File

@@ -88,7 +88,7 @@ class CloudflarePeer extends Peer<{
context: _cf.ExecutionContext;
};
}> {
get id() {
get addr() {
return undefined;
}

View File

@@ -73,7 +73,7 @@ class DenoPeer extends Peer<{
info: ServeHandlerInfo;
};
}> {
get id() {
get addr() {
// @ts-expect-error types missing
return this.ctx.deno.ws.remoteAddress;
}

View File

@@ -114,7 +114,7 @@ class NodePeer extends Peer<{
ws: WebSocketT;
};
}> {
get id() {
get addr() {
const socket = this.ctx.node.req.socket;
if (!socket) {
return undefined;

View File

@@ -149,7 +149,7 @@ class UWSPeer extends Peer<{
_headers: HeadersInit | undefined;
_decoder = new TextDecoder();
get id() {
get addr() {
try {
const addr = this._decoder.decode(
this.ctx.uws.ws?.getRemoteAddressAsText(),

View File

@@ -11,12 +11,21 @@ const ReadyStateMap = {
} as const;
export abstract class Peer<AdapterContext = any> implements WSRequest {
_subscriptions: Set<string> = new Set();
private _subscriptions: Set<string> = new Set();
constructor(public ctx: AdapterContext) {}
static _idCounter = 0;
private _id: string;
get id(): string | undefined {
return "??";
constructor(public ctx: AdapterContext) {
this._id = ++Peer._idCounter + "";
}
get id(): string {
return this._id.toString();
}
get addr(): string | undefined {
return undefined;
}
get url(): string {
@@ -46,10 +55,15 @@ export abstract class Peer<AdapterContext = any> implements WSRequest {
}
toString() {
return `${this.id || ""}${this.readyState === 1 || this.readyState === -1 ? "" : ` [${ReadyStateMap[this.readyState]}]`}`;
return `#${this.id}`;
}
[Symbol.for("nodejs.util.inspect.custom")]() {
return this.toString();
const _addr = this.addr || "??";
const _state =
this.readyState === 1 || this.readyState === -1
? ""
: ` [${ReadyStateMap[this.readyState]}]`;
return `Peer<${_addr}${_state}>`;
}
}