Open himanshu-ntml opened 1 week ago
I was able to solve... there was some mistake.
import { generateHonoObject } from 'hono-do';
import { defineStorage } from 'hono-do/storage';
import { cors } from 'hono/cors';
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;
id: string;
}[];
}
}
export const Chat = generateHonoObject('/chat', async (app, state, vars) => {
const [getValue, setValue] = await defineStorage(state.storage, 'messages', []);
vars.messages = (await getValue()) || [];
app.get('/connect', async (c) => {
if (c.req.header('Upgrade') === 'websocket') {
return handleWebSocketUpgrade();
}
return c.text('Not found', 404);
});
app.use(
'*',
cors({
origin: ['http://localhost:3000', 'http://localhost:8008', '*'],
allowHeaders: ['Content-Type', 'Authorization'],
allowMethods: ['POST', 'GET', 'OPTIONS', 'DELETE', 'PATCH'],
exposeHeaders: ['Content-Length'],
maxAge: 600,
credentials: true,
})
);
app.options('*', (c) => {
return c.text('', 204);
});
app.delete('/:id', async (c) => {
const id = c.req.param('id');
const [getValue, setValue] = await defineStorage(state.storage, 'messages', []);
let messages = await getValue();
const initialLength = messages.length;
messages = messages.filter((message) => message.id !== id);
if (messages.length === initialLength) {
return c.text('Message not found', 404);
}
await setValue(messages);
return c.text('Message deleted successfully', 200);
});
app.get('/messages', async (c) => {
const messages = await getValue();
// setValue([]);
return c.json(messages);
});
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, 'messages', []);
let oldMessages = await getValue();
try {
const parsedMsg = JSON.parse(msg.toString());
oldMessages.push(parsedMsg);
await setValue(oldMessages);
state.getWebSockets().forEach((ws) => {
const { clientId } = ws.deserializeAttachment();
if (clientId === senderClientId) {
return;
}
try {
ws.send(msg.toString());
} catch (error) {
ws.close();
}
});
} catch (error) {
console.error('Error parsing or storing message:', error);
}
});
Now i am running into another issue. I am not able to fetch all the messages using the get route in another nextjs app. I was running into cors error and tried the above code to solve the cors but now i am getting "Can't modify immtable headers"
✘ [ERROR] TypeError: Can't modify immutable headers.
at set res
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/context.js:71:24)
at dispatch
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/compose.js:43:17)
at async cors2
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/middleware/cors/index.js:70:5)
at async dispatch
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/compose.js:29:17)
at null.<anonymous> (async
file:///Users/nicolethomas/Desktop/Membership/hono/.wrangler/tmp/dev-AmZfOC/index.js:2764:25)
at async jsonError
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)
at async drainBody
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts:5:10)
TypeError: Can't modify immutable headers.
at set res
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/context.js:71:24)
at dispatch
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/compose.js:43:17)
at async cors2
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/middleware/cors/index.js:70:5)
at async dispatch
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/hono/dist/compose.js:29:17)
at null.<anonymous> (async
file:///Users/nicolethomas/Desktop/Membership/hono/.wrangler/tmp/dev-AmZfOC/index.js:2764:25)
at async jsonError
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)
at async drainBody
(file:///Users/nicolethomas/Desktop/Membership/hono/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts:5:10)
[wrangler:inf] GET /chat/connect 500 Internal Server Error (12ms)
[wrangler:inf] GET /chat/messages 500 Internal Server Error (16ms)
[wrangler:inf] GET /chat/messages 500 Internal Server Error (15ms)
Thank you for asking, I'll look at it later!
Hi, @himanshu-ntml
I think this Can't modify immutable headers.
issue can't be solved without also looking at the code of the main workers that proxy Durable Objects.
I tried it in my environment to test it and it did not have such an effect.
@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.