Skip to content

Having issues making messages persist #46

@himanshu-ntml

Description

@himanshu-ntml

@sor4chi Thank you so much for making hono-do library. It makes it so easy to work with DO and websockets.

I am trying to use it to build a real-time quiz app where I want to use DO and web sockets for real-time results. I am trying to implement persistence in hibernate-chat example. But I am running into issues. Could you please help? I am not sure whether my approach is right or wrong or i am missing something.

import { generateHonoObject } from 'hono-do';
import { defineStorage } from 'hono-do/storage';

function uuidv4() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0,
      v = c == 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

declare module 'hono-do' {
  interface HonoObjectVars {
    messages: {
      timestamp: string;
      text: string;
    }[];
  }
}

export const Chat = generateHonoObject('/chat', async (app, state, vars) => {
  let { storage } = state;
  const [getValue] = await defineStorage(state.storage, 'value', {});

  // console.log(await state.storage.get('value'), 'aaa');

  vars.messages = [];

  app.get('/messages', async (c) => c.json(await getValue()));

  app.get('/websocket', async (c) => {
    if (c.req.header('Upgrade') === 'websocket') {
      return await handleWebSocketUpgrade();
    }
    return c.text('Not found', 404);
  });

  async function handleWebSocketUpgrade() {
    const [client, server] = Object.values(new WebSocketPair());
    const clientId = uuidv4();
    state.acceptWebSocket(server);
    server.serializeAttachment({ clientId });

    return new Response(null, { status: 101, webSocket: client });
  }
});

Chat.webSocketMessage(async (webSocket, msg, state, vars) => {
  const { clientId: senderClientId } = await webSocket.deserializeAttachment();
  const [getValue, setValue] = await defineStorage(state.storage, 'value', {});
  let oldMessages: any = await getValue();
  console.log('msg', msg, vars, state, webSocket);
  oldMessages.push(msg);
  // await state.storage.put('value', oldMessages);
  setValue(oldMessages);
  state.getWebSockets().forEach((ws) => {
    const { clientId } = ws.deserializeAttachment();
    if (clientId === senderClientId) {
      return;
    }
    try {
      vars.messages.push(JSON.parse(msg.toString()));
      ws.send(msg.toString());
    } catch (error) {
      ws.close();
    }
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions