Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
partyserver
Advanced tools
Build real-time applications powered by [Durable Objects](https://developers.cloudflare.com/durable-objects/), inspired by [PartyKit](https://www.partykit.io/).
Build real-time applications powered by Durable Objects, inspired by PartyKit.
npm install partyserver
PartyServer enhances Durable Objects with the following features:
routePartykitRequest()
to get PartyKit-style route matching.wrangler.toml
. We may add this in the future.Here's an example of how to use PartyServer:
Write your code:
// index.ts
import { routePartykitRequest, Server } from "partyserver";
// Define your Server
export class MyServer extends Server {
onConnect(connection) {
console.log("Connected", connection.id, "to server", this.name);
}
onMessage(connection, message) {
console.log("Message from", connection.id, ":", message);
// Send the message to every other connection
this.broadcast(message, [connection.id]);
}
}
export default {
// Set up your fetch handler to use configured Servers
fetch(request, env) {
return (
routePartykitRequest(request, env) ||
new Response("Not Found", { status: 404 })
);
}
};
And configure your wrangler.toml
:
name = "my-partyserver-app"
main = "index.ts"
[[durable_objects.bindings]]
name = "MyServer"
class_name = "MyServer"
[[migrations]]
tag = "v1" # Should be unique for each entry
new_classes = ["MyServer"]
You can connect to the server from a client (like a browser or a mobile app) using partysocket
or any other WebSocket client.
import { PartySocket } from "partysocket";
const socket = new PartySocket({
host: "https://my-partyserver-app.threepointone.workers.dev", // optional, defaults to window.location.host,
party: "my-server", // the server name. if you use routePartykitRequest, it automatically uses the kebab-cased version of the binding name (MyServer -> my-server)
room: "my-room"
});
See the /fixtures
folder for more specific examples.
Server
Server
is a class that extends DurableObject
. You can override the following methods on Server
to add custom behavior:
These methods can be optionally async
:
onStart()
: Called when the server starts for the first time or after waking up from hibernation. You can use this to load data from storage and perform other initialization, such as retrieving data or configuration from other services or databases.
onConnect(connection, context)
- Called when a new websocket connection is established. You can use this to set up any connection-specific state or perform other initialization. Receives a reference to the connecting Connection
, and a ConnectionContext
that provides information about the initial connection request.
onMessage(connection, message)
- Called when a message is received on a connection.
onClose(connection, code, reason, wasClean)
- Called when a connection is closed by a client. By the time onClose
is called, the connection is already closed and can no longer receive messages.
onError(connection, error)
- Called when an error occurs on a connection.
onRequest(request): Response
- Called when a request is made to the server. This is useful for handling HTTP requests in addition to WebSocket connections.
onAlarm()
- Called when an alarm is triggered. You can set an alarm by calling this.ctx.storage.setAlarm(Date)
. Read more about Durable Objects alarms here.
getConnectionTags(connection, context): string[]
- You can set additional metadata on connections by returning them from getConnectionTags()
, and then filter connections based on the tag with this.getConnections
.
broadcast(message, exclude = [])
- Send a message to all connections, optionally excluding connection ids listed in the second array parameter.
getConnections(tags = [])
- Get all currently connected WebSocket connections, optionally filtered by tags set by getConnectionTags()
. Returns an iterable list of Connection
.
getConnection(id)
- Get a connection by its ID.
.name
- (readonly) this is automatically set to the server's "name", determined by getServerByName()
or routePartykitRequest()
.
.ctx
- the context object for the Durable Object, containing references to storage
.env
- the environment object for the Durable Object, defined by bindings and other configuration in your wrangler.toml
configuration file.
fetch(request)
- PartyServer overrides the fetch
method to add the lifecycle methods to the server instance. In most cases you don't have to implement this mehod yourself. If you do (for example, to add request handling before any lifecycle methods are called), make sure to call super.fetch(request)
as appropriate to ensure the lifecycle methods are called.
alarm()
- You should not implement/override this yourself, use onAlarm()
instead. This method is called whenever an alarm is triggered. This is the only way to run code after the server has been evicted. Read more about alarms here.
Do not implement any of these methods on your server class: webSocketMessage
/webSocketClose
/ webSocketError
/ alarm. We override them to call the lifecycle methods in hibernation mode.
A connection is a standard WebSocket with the following additional properties:
id
- A unique ID for the connectiontags
- An array of tags assigned to the connection (TODO)server
- The server name the connection is instate
- Arbitrary state data (up to 2KB) that can be set on the connection using connection.setState()
You can enable hibernation by setting a static options
property on your Server class. This allows the server to hibernate when not in use and wake up when a new connection is established. All lifecycle hooks will be called as expected when the server wakes up.
export class MyServer extends Server {
static options = {
hibernate: true
};
// ...
}
getServerByName(namespace, name, {locationHint, jurisdiction}): Promise<DurableObjectStub>
- Create a new Server with a specific name. Optionally pass a locationHint
to specify the location or jurisdiction
to specify the jurisdiction of the server.
routePartykitRequest(request, env, {locationHint, jurisdiction, prefix = 'parties'}): Promise<Response | null>
- Match a request to a server. Takes a URL of the form /${prefix}/:server/:name
and matches it with any namespace named :server
(case insensitive) and a server named :name
. Optionally pass a locationHint
to specify the location or jurisdiction
to specify the jurisdiction of the server.
"Wait", I hear you say, "this looks a lot like Erlang/Elixir's actor model!" And you'd be right! Durable Objects are inspired by the actor model/GenServer and aims to provide a similar experience for developers building applications on Cloudflare Workers. It's implemented fully in the infrastructure layer, so you don't have to maintain your own infrastructure.
Instead of spawning "actors", you create servers that handle connections and messages. This is because Durable Objects are designed to be long-lived and stateful, so it makes sense to model them as servers that can handle multiple connections.
It differs in a specific way: There's no "terminate" handler, because a Durable Object can "shut down" / get evicted at any time, and we can't reliably call a "terminate" handler. Instead, you can set an alarm to run some cleanup code at some point in the future.
FAQs
Build real-time applications powered by [Durable Objects](https://developers.cloudflare.com/durable-objects/), inspired by [PartyKit](https://www.partykit.io/).
We found that partyserver demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.