Comments (2)
Hi, maybe you can give this a try.
// Counter DO class
import { Router } from 'worktop'
import { reply } from 'worktop/response'
import { Actor } from 'worktop/cfw.durable'
import type { Durable } from 'worktop/cfw.durable'
import type { WebSocket } from 'worktop/cfw.ws'
type Connection = {
ws: WebSocket
}
function replyWS(socket: WebSocket, type: string, data: number | string) {
let message = JSON.stringify({ type, data })
socket.send(message)
}
export class Counter extends Actor {
count: number
API = this.router()
connections: Connection[] = []
storage: Durable.Storage
async setup(state: Durable.State, bindings: Bindings) {
this.count = (await state.storage.get(`count`)) || 0
this.storage = state.storage
}
receive = this.API.run
onconnect = (req: Request, server: WebSocket) => {
this.connections.push({ ws: server })
server.addEventListener(`message`, this.handleMessage)
server.addEventListener(`close`, this.handleCloseOrError)
server.addEventListener(`error`, this.handleCloseOrError)
replyWS(server, `count/LOADED`, this.count)
}
router() {
const API = new Router()
API.add(`GET`, `/`, () => {
return reply(200, this.count)
})
API.add(`GET`, `/ws`, async (req) => {
const res = await this.connect(req)
return res
})
return API
}
broadcast() {
this.connections.forEach((client) => {
try {
replyWS(client.ws, `count/UPDATED`, this.count)
} catch (err) {}
})
}
handleMessage = async (e) => {
try {
const event = JSON.parse(e.data)
switch (event.type) {
case 'increment':
await this.storage.put('count', ++this.count)
break
case 'decrement':
await this.storage.put('count', --this.count)
break
default:
break
}
this.broadcast()
} catch (err) {}
}
handleCloseOrError = (e) => {
this.connections = this.connections.filter(({ ws }) => ws !== e.target)
}
}
Then in your main router
function requestFromCounterDO(req, ctx) {
const { id } = ctx.params
const url = new URL(req.url)
// /room/1/ => '/'
// /room/1/ws -> /ws
// matches DO class router
url.pathname = url.pathname.replace(`/room/${id}`, ``)
// get a specific durable object based on room id
const namespace = ctx.bindings.COUNTER
const objectId = namespace.idFromName(id)
const object = namespace.get(objectId)
return object.fetch(url, req)
}
// REST endpoint
API.add('GET', '/room/:id/', requestFromCounterDO)
// ws endpoint
API.add('GET', '/room/:id/ws', requestFromCounterDO)
from worktop.
Hey,
There's an Actor
class that's always been available from the cfw.durable
module. It includes WS utilities/hooks. Here's an example using it with WebSockets. The Counter4
below it incorporates the worktop Router
class for more routing control over your Actor.
Hope that helps~!
Closing but please follow up with any additional questions / comments.
from worktop.
Related Issues (20)
- Using Worktop in a Pages website HOT 3
- Use Sveltekit and worktop together? HOT 2
- How to set multiple cookies? HOT 2
- Worktop Middlewares Example HOT 4
- The example of timing requests might be misleading HOT 1
- Using official Cloudflare types HOT 4
- Can I use Worktop with Fastly Compute@Edge? HOT 1
- Is it going to be official by cloudflare?
- Cache API and KV: Concerns/Questions/Usage HOT 1
- How to access `.env` with Wrangler 2 HOT 2
- Provide a "test" module HOT 4
- Serving HTML files HOT 6
- How to use with cron / scheduled event ? HOT 2
- Is `worktop@next` safe to use in production? HOT 2
- Add generic typing for Router.add handler
- The uploaded script has no registered event handlers. [API code: 10068] HOT 1
- Add sub-routers HOT 2
- Node 16+ ESM TypeScript error HOT 1
- `isCacheable` allowed cache by default if the `cache-control` header is empty may leading to a security flaw in ssg content HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from worktop.