mirror of
https://github.com/LukeHagar/crossws.git
synced 2025-12-06 04:19:26 +00:00
feat: auto generated peer id
This commit is contained in:
@@ -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`
|
||||
|
||||
|
||||
@@ -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() });
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>>(
|
||||
},
|
||||
};
|
||||
},
|
||||
close(peer, details) {
|
||||
console.log(`[ws] close ${peer}`, details);
|
||||
},
|
||||
error(peer, error) {
|
||||
console.log(`[ws] error ${peer}`, error);
|
||||
},
|
||||
});
|
||||
|
||||
const resolve: ResolveHooks = (info) => {
|
||||
return {
|
||||
open: (peer) => {
|
||||
peer.send({
|
||||
message: {
|
||||
info: {
|
||||
url: info.url,
|
||||
headers:
|
||||
info.headers && Object.fromEntries(new Headers(info.headers)),
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return adapter({
|
||||
...options,
|
||||
hooks,
|
||||
resolve,
|
||||
// resolve,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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}]`;
|
||||
|
||||
@@ -88,7 +88,7 @@ class CloudflarePeer extends Peer<{
|
||||
context: _cf.ExecutionContext;
|
||||
};
|
||||
}> {
|
||||
get id() {
|
||||
get addr() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
26
src/peer.ts
26
src/peer.ts
@@ -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}>`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user