-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
199 additions
and
105 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 was deleted.
Oops, something went wrong.
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,47 @@ | ||
--- | ||
icon: material-symbols-light:data-object | ||
--- | ||
|
||
# Hooks | ||
|
||
> Using WebSocket hooks API, you can define a WebSocket server that works across runtimes with same synax. | ||
CrossWS provides a cross-platform API to define WebSocket servers. An implementation with these hooks works across runtimes without needing you to go into details of any of them (while you always have the power to control low-level hooks). You can only define the life-cycle hooks that you only need and only those will be called on runtime. | ||
|
||
> [!IMPORTANT] | ||
> CrossWS API is still under development and can change. | ||
> [!TIP] | ||
> Using `defineHooks` to define hooks, we have type support and IDE auto-completion even if not using typescript. This utility does nothing more and you can use a plain object as well if you prefer to. | ||
```ts | ||
import { defineHooks } from "crossws"; | ||
|
||
const hooks = defineHooks({ | ||
upgrade(req) { | ||
console.log(`[ws] upgrading ${req.url}...`) | ||
return { | ||
headers: {} | ||
} | ||
} | ||
|
||
open(peer) { | ||
console.log(`[ws] open: ${peer}`); | ||
}, | ||
|
||
message(peer, message) { | ||
console.log("[ws] message", peer, message); | ||
if (message.text().includes("ping")) { | ||
peer.send("pong"); | ||
} | ||
}, | ||
|
||
close(peer, event) { | ||
console.log("[ws] close", peer, event); | ||
}, | ||
|
||
error(peer, error) { | ||
console.log("[ws] error", peer, error); | ||
}, | ||
}; | ||
``` |
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,53 @@ | ||
--- | ||
icon: mynaui:api | ||
--- | ||
|
||
# Peer | ||
|
||
> Peer object allows easily interacting with connected clients. | ||
Websocket [hooks](/guide/hooks) accept a peer instance as their first argument. You can use peer object to get information about each connected client or send a message to them. | ||
|
||
> [!TIP] | ||
> You can safely log a peer instance to the console using `console.log` it will be automatically stringified with useful information including the remote address and connection status! | ||
## API | ||
|
||
### `peer.send(message, compress)` | ||
|
||
Send a message to the connected client | ||
|
||
### `peer.id` | ||
|
||
The peer address or unique id (might be `undefined`) | ||
|
||
### `peer.readyState` | ||
|
||
Client connection status (might be `undefined`) | ||
|
||
:read-more{to="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState" title="readyState in MDN"} | ||
|
||
### `peer.ctx` | ||
|
||
`peer.ctx` is an object that holds adapter specific context. It is scoped with `peer.ctx.[name]`. | ||
|
||
> [!NOTE] | ||
> `ctx`` is an advanced namespace and API changes might happen, so don't rely on it as much aspossible! | ||
### `peer.subscribe(channel)` | ||
|
||
Join a boradcast channel. | ||
|
||
:read-more{to="/guide/pubsub"} | ||
|
||
### `peer.unsubscribe(channel)` | ||
|
||
Leave a boradcast channel. | ||
|
||
:read-more{to="/guide/pubsub"} | ||
|
||
### `peer.publish(channel, message)` | ||
|
||
Boradcast a message to the channel. | ||
|
||
:read-more{to="/guide/pubsub"} |
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,24 @@ | ||
--- | ||
icon: solar:letter-line-duotone | ||
--- | ||
|
||
# Message | ||
|
||
On `message` [hook](/guide/hooks), you receive a message object containing an incoming message from the client. | ||
|
||
> [!TIP] | ||
> You can safely log `message` object to the console using `console.log` it will be automatically stringified! | ||
## API | ||
|
||
### `message.text()` | ||
|
||
Get stringified text version of the message | ||
|
||
### `message.rawData` | ||
|
||
Raw message data | ||
|
||
### `message.isBinary` | ||
|
||
Indicates if the message is binary (might be `undefined`) |
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,37 @@ | ||
--- | ||
icon: simple-icons:googlepubsub | ||
--- | ||
|
||
# Pub / Sub | ||
|
||
CrossWS supports native pub-sub API integration. A [peer](/guide/peer) can be subscribed to a set of named channels using `peer.subscribe(<name>)`. Messages can be published tro a channel using `peer.publish(<name>, <message>)`. | ||
|
||
> [!IMPORTANT] | ||
> Native pub/sub is currently only available for [Bun](/adapters/bun) and (Node.js with uWebSockets)(http://localhost:4000/adapters/node#uwebsockets). | ||
```js | ||
import { defineHooks } from "crossws"; | ||
|
||
const hooks = defineHooks({ | ||
open(peer) { | ||
// Send welcome to the new client | ||
peer.send("Welcome to the server!"); | ||
|
||
// Join new client to the "chat" channel | ||
peer.subscribe("chat"); | ||
|
||
// Notify every other connected client | ||
peer.publish("chat", `[system] ${peer} joined!`); | ||
}, | ||
|
||
message(peer, message) { | ||
// The server re-broadcasts incoming messages to everyone | ||
peer.publish("chat", `[${peer}] ${message}`); | ||
}, | ||
|
||
close(peer) { | ||
peer.publish("chat", `[system] ${peer} has left the chat!`); | ||
peer.unsubscribe("chat"); | ||
}, | ||
}); | ||
``` |
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,27 @@ | ||
--- | ||
icon: tabler:route | ||
--- | ||
|
||
# Resolver API | ||
|
||
When integrating WebSockets with larger projects, it is often needed to dynamically route an incoming event to websocket hooks. CrossWS provides a very simple mechanism to do this using resolver API. | ||
|
||
> [!TIP] | ||
> Resovler supports async results. This allows implementing lazy loading. | ||
```js | ||
// https://crossws.unjs.io/adapters | ||
import wsAdapter from "crossws/adapters/<adapter>"; | ||
|
||
import { defineHooks } from "crossws"; | ||
|
||
const websocket = wsAdapter({ | ||
async resolve(req) { | ||
// TODO: Resolve hooks based on req.url, req.headers | ||
// You can return undefined in case there is no match | ||
return { | ||
/* resolved hooks */ | ||
}; | ||
}, | ||
}); | ||
``` |