HTMX、WebSocket、Hono でチャットする

PHPz
リリース: 2024-08-07 09:07:11
オリジナル
385 人が閲覧しました

Chat with HTMX, WebSockets and Hono

Last week, I wrote about tweaking htmx to display instant messages. A week into using HTMX, I needed more. I wanted a better way to stream HTML from the server, using JSX components instead of plain HTML strings for better code usability.

? Quick reminder: if you find this useful, please give it a thumbs up! Your support helps me create more content.

Tools I Used:

  • HTMX
  • HTMX Websockets Extension
  • Honofor the backend
  • Websockets- client-side

The idea is simple. My Conversation component is wrapped in a div with hx-ext="ws", which connects to my backend when rendered.

export const Conversation = (props: { messages: Message[] }) => ( 
{props.messages.reverse().map((message) => (
))}
);
ログイン後にコピー

Next important thing is the InputMessageForm. Just add ws-send to the form, and it will send a message where the key is the textarea’s ID (messageInput) with its value.

export const InputMessageForm = () => ( 
);
ログイン後にコピー

Websockets - Server

Here’s the full code block for the Hono server. Some console logs for opening and closing connection. onMessage is where the magic happens.

get( '/chatroom-ws', upgradeWebSocket((c) => { return { onOpen: () => { console.log('WS Connection open'); }, onClose: () => { console.log('WS Connection closed'); }, onMessage: async (event, ws) => { const { userMessage } = JSON.parse(event.data.toString()); console.log('Got user message', userMessage); const inputArea = await c.html( 
, ); ws.send(await inputArea.text()); const htmlUser = await c.html(
, ); ws.send(await htmlUser.text()); const response = await talk(userMessage); const htmlAgent = await c.html(
, ); ws.send(await htmlAgent.text()); }, }; }), );
ログイン後にコピー

So the flow is:

  1. Receive the query
  2. Send back empty just to make it clean. There is no hx-swap-oob specified so its True by default. That means that it will find the element with id=query-submit-form and swap it.
  3. Send back the component with the user message. Here hx-swap-oob is specified to beforeend which simply means that it will be added to existing messages.
  4. talk → here comes your logic. I’m talking to AI assistant so making some external API calls.
  5. Send back the component with assistant answer. The same as step 3 but the component is different.

Problems I found

Sending response back was a bit problematic since docs are hmm… not that easy to understand I think. There is even an issue created to fix this: Improve documentation for websocket extension. That helped me a lot!

So the most important thing is:

You need to send back string, that parses to html that has the same id as the thing you want to swap!

So the problem nr. 1

I accidentally sent back something like this:

JSON.stringify('
test 123
') // '"
test 123
"'
ログイン後にコピー

This is wrong. Note the ID and escape characters! Don’t stringify the string here.

The problem nr. 2

You might think you can return something and it will get swapped where you want. Not exactly. The firstdivis just information for HTMX on what to do. At least I understand it this way ?.

I’m returning html like this:

ログイン後にコピー

Only is appended inside the existing

on the client side.

End result

https://assets.super.so/c0fc84d8-fb32-4194-8758-4be657666aab/videos/c814dcd2-b9e9-4bb2-b8db-2ed9cd7819b7/lucy-chat-example.mov

? Does this post help you? Please spam the like button! Your support is awesome. Thanks!

Want to Know More?

Stay tuned for more insights and tutorials! Visit My Blog ?

以上がHTMX、WebSocket、Hono でチャットするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!