{"id":65957,"date":"2024-06-10T06:32:10","date_gmt":"2024-06-10T03:02:10","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/"},"modified":"2024-06-10T06:32:10","modified_gmt":"2024-06-10T03:02:10","slug":"hono-simple-messaging-app-using-bun-and-websocket-mnk","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/","title":{"rendered":"[Hono] \u0628\u0631\u0646\u0627\u0645\u0647 \u067e\u06cc\u0627\u0645 \u0631\u0633\u0627\u0646\u06cc \u0633\u0627\u062f\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Bun \u0648 WebSocket"},"content":{"rendered":"<div data-article-id=\"1877504\" id=\"article-body\">\n<p>\u0645\u0627 \u0627\u063a\u0644\u0628 \u0634\u0627\u0647\u062f \u0627\u062c\u0631\u0627\u06cc WebSocket \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0686\u0627\u0631\u0686\u0648\u0628 Express \u0648 Socket.io \u0647\u0633\u062a\u06cc\u0645.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0628\u0647 \u0646\u0638\u0631 \u0645\u06cc\u200c\u0631\u0633\u062f \u0646\u0645\u0648\u0646\u0647\u200c\u0647\u0627\u06cc \u06a9\u0645\u062a\u0631\u06cc \u0627\u0632 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc WebSocket \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Hono \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f\u060c \u0686\u0627\u0631\u0686\u0648\u0628\u06cc \u06a9\u0647 \u0634\u0628\u06cc\u0647 Express \u0627\u0633\u062a \u0627\u0645\u0627 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0648 \u0633\u0628\u06a9\u200c\u062a\u0631 \u0627\u0633\u062a.  \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u067e\u06cc\u0627\u0645 \u0631\u0633\u0627\u0646\u06cc \u0633\u0627\u062f\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Hono \u0648 Bun \u06a9\u0647 \u06cc\u06a9 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627 \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a \u0627\u0633\u062a \u0631\u0627 \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0645.<\/p>\n<p>\u0627\u06cc\u0646 \u067e\u0631\u0648\u0698\u0647 \u0633\u0627\u062e\u062a\u0627\u0631 \u0633\u0627\u062f\u0647 \u0627\u06cc \u062f\u0627\u0631\u062f \u0648 \u0627\u0645\u06a9\u0627\u0646 \u06af\u0633\u062a\u0631\u0634 \u0648\u06cc\u0698\u06af\u06cc \u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0645\u0627\u0646\u0646\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0648 \u0686\u0646\u062f\u06cc\u0646 \u0639\u0645\u0644\u06a9\u0631\u062f \u0645\u062f\u06cc\u0631\u06cc\u062a \u0627\u062a\u0627\u0642 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f.  \u062f\u0631 \u0627\u0628\u062a\u062f\u0627 \u0642\u0635\u062f \u062f\u0627\u0634\u062a\u0645 \u0645\u0642\u0627\u0644\u0647 \u0627\u06cc \u0628\u0627 \u0645\u062d\u0648\u0631\u06cc\u062a WebSocket \u0628\u0646\u0648\u06cc\u0633\u0645 \u06a9\u0647 \u062f\u0631 \u06a9\u0645\u062a\u0631 \u0627\u0632 3 \u062f\u0642\u06cc\u0642\u0647 \u0642\u0627\u0628\u0644 \u062e\u0648\u0627\u0646\u062f\u0646 \u0628\u0627\u0634\u062f\u060c \u0627\u0645\u0627 \u062c\u0630\u0627\u0628\u06cc\u062a Hono \u0645\u0631\u0627 \u062c\u0630\u0628 \u06a9\u0631\u062f \u0648 \u062d\u062c\u0645 \u0645\u0642\u0627\u0644\u0647 \u0628\u06cc\u0634 \u0627\u0632 \u062d\u062f \u0627\u0646\u062a\u0638\u0627\u0631 \u0627\u0641\u0632\u0627\u06cc\u0634 \u06cc\u0627\u0641\u062a.  \u062d\u0627\u0644\u0627 \u0628\u06cc\u0627\u06cc\u06cc\u062f \u0628\u0647 \u062c\u0632\u0626\u06cc\u0627\u062a \u0628\u067e\u0631\u062f\u0627\u0632\u06cc\u0645.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter-rtl ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">\u0641\u0647\u0631\u0633\u062a \u0645\u0637\u0627\u0644\u0628<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#%D9%BE%D8%B4%D8%AA%D9%87_%D9%81%D9%86%D8%A7%D9%88%D8%B1%DB%8C\" >\u067e\u0634\u062a\u0647 \u0641\u0646\u0627\u0648\u0631\u06cc<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#%D8%B3%D8%A7%D8%AE%D8%AA%D8%A7%D8%B1_%D9%BE%D8%B1%D9%88%DA%98%D9%87\" >\u0633\u0627\u062e\u062a\u0627\u0631 \u067e\u0631\u0648\u0698\u0647<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#UI\" >UI<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#%D9%87%D9%88%D9%86%D9%88_%DA%86%DB%8C%D8%B3%D8%AA%D8%9F\" >\u0647\u0648\u0646\u0648 \u0686\u06cc\u0633\u062a\u061f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#Bun_%DA%86%DB%8C%D8%B3%D8%AA%D8%9F\" >Bun \u0686\u06cc\u0633\u062a\u061f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#WebSocket_%DA%86%DB%8C%D8%B3%D8%AA%D8%9F\" >WebSocket \u0686\u06cc\u0633\u062a\u061f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#%D9%BE%DB%8C%D8%A7%D8%AF%D9%87_%D8%B3%D8%A7%D8%B2%DB%8C\" >\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#Backend_%D9%BE%DB%8C%DA%A9%D8%B1%D8%A8%D9%86%D8%AF%DB%8C_WebSocket\" >Backend: \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc WebSocket<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#Backend_%D8%A7%D8%AA%D8%B5%D8%A7%D9%84_%D9%88_%D9%82%D8%B7%D8%B9_%D8%A7%D8%AA%D8%B5%D8%A7%D9%84_WebSocket\" >Backend: \u0627\u062a\u0635\u0627\u0644 \u0648 \u0642\u0637\u0639 \u0627\u062a\u0635\u0627\u0644 WebSocket<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#Backend_messages_Endpoint\" >Backend: \/messages Endpoint<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#Frontend_%D8%B1%D8%A7%D9%87_%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C_WebSocket\" >Frontend: \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc WebSocket<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/nabfollower.com\/blog\/hono-simple-messaging-app-using-bun-and-websocket-mnk\/#Frontend_%D8%A7%D8%B1%D8%B3%D8%A7%D9%84_%D9%BE%DB%8C%D8%A7%D9%85\" >Frontend: \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"%D9%BE%D8%B4%D8%AA%D9%87_%D9%81%D9%86%D8%A7%D9%88%D8%B1%DB%8C\"><\/span>\n<p>  \u067e\u0634\u062a\u0647 \u0641\u0646\u0627\u0648\u0631\u06cc<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Frontend:<\/p>\n<p>Backend:<\/p>\n<p>\u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627 \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a (\u0647\u0645 \u0641\u0631\u0627\u0646\u062a \u0627\u0646\u062f \u0648 \u0647\u0645 \u0628\u0627\u0637\u0646):<\/p>\n<h2><span class=\"ez-toc-section\" id=\"%D8%B3%D8%A7%D8%AE%D8%AA%D8%A7%D8%B1_%D9%BE%D8%B1%D9%88%DA%98%D9%87\"><\/span>\n<p>  \u0633\u0627\u062e\u062a\u0627\u0631 \u067e\u0631\u0648\u0698\u0647<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>\u251c\u2500\u2500 frontend\n\u2502   \u251c\u2500\u2500 src\n\u2502   \u2502   \u251c\u2500\u2500 App.css\n\u2502   \u2502   \u251c\u2500\u2500 App.tsx\n\u2502   \u2502   \u251c\u2500\u2500 index.css\n\u2502   \u2502   \u251c\u2500\u2500 main.tsx\n\u2502   \u2502   \u2514\u2500\u2500 vite-env.d.ts\n\u2502   \u251c\u2500\u2500 bun.lockb\n\u2502   \u251c\u2500\u2500 index.html\n\u2502   \u251c\u2500\u2500 package.json\n\u2502   \u251c\u2500\u2500 tsconfig.json\n\u2502   \u251c\u2500\u2500 tsconfig.node.json\n\u2502   \u2514\u2500\u2500 vite.config.ts\n\u251c\u2500\u2500 server\n\u2502   \u2514\u2500\u2500 index.ts\n\u251c\u2500\u2500 shared\n\u2502   \u251c\u2500\u2500 constants.ts\n\u2502   \u2514\u2500\u2500 types.ts\n\u251c\u2500\u2500 bun.lockb\n\u251c\u2500\u2500 package.json\n\u2514\u2500\u2500 tsconfig.json\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<ul>\n<li>\u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0631\u06cc\u0634\u0647 \u0648 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0633\u0631\u0648\u0631: \u0628\u0631\u0646\u0627\u0645\u0647 Hono<\/li>\n<li>\u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc Frontend: \u0628\u0631\u0646\u0627\u0645\u0647 React<\/li>\n<li>\u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u0634\u062a\u0631\u0627\u06a9\u06cc: \u062b\u0627\u0628\u062a \u0647\u0627 \u0648 \u0627\u0646\u0648\u0627\u0639\u06cc \u06a9\u0647 \u0628\u0647 \u0637\u0648\u0631 \u0645\u0634\u062a\u0631\u06a9 \u0628\u06cc\u0646 frontend \u0648 backend \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u0646\u062f<\/li>\n<\/ul>\n<p>\u0645\u0646 \u0641\u0627\u06cc\u0644 \u0647\u0627\u06cc \u062a\u0646\u0638\u06cc\u0645\u0627\u062a TailwindCSS \u0648 \u063a\u06cc\u0631\u0647 \u0631\u0627 \u062d\u0630\u0641 \u06a9\u0631\u062f\u0647 \u0627\u0645. \u0633\u0627\u062e\u062a\u0627\u0631 \u0628\u0647 \u06af\u0648\u0646\u0647 \u0627\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 Hono \u0628\u0631\u0646\u0627\u0645\u0647 React \u0631\u0627 \u0645\u06cc \u067e\u06cc\u0686\u062f.  \u0627\u06cc\u0646 \u06cc\u06a9 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u0622\u0633\u0627\u0646 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u062f\u0631 \u0647\u0646\u06af\u0627\u0645 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc RPC (\u062a\u0645\u0627\u0633 \u0631\u0648\u06cc\u0647 \u0627\u0632 \u0631\u0627\u0647 \u062f\u0648\u0631) \u0628\u0648\u062f\u060c \u06a9\u0647 \u062f\u0631 \u0622\u0646 frontend \u0648 backend \u0648\u0627\u0628\u0633\u062a\u06af\u06cc\u200c\u0647\u0627 \u0648 \u062a\u0639\u0627\u0631\u06cc\u0641 \u0646\u0648\u0639 Hono \u0631\u0627 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0645\u06cc\u200c\u06af\u0630\u0627\u0631\u0646\u062f.<\/p>\n<p>\u0645\u062e\u0632\u0646:<br \/>https:\/\/github.com\/yutakusuno\/bun-hono-react-websocket<\/p>\n<h2><span class=\"ez-toc-section\" id=\"UI\"><\/span>\n<p>  UI<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><\/p>\n<h2><span class=\"ez-toc-section\" id=\"%D9%87%D9%88%D9%86%D9%88_%DA%86%DB%8C%D8%B3%D8%AA%D8%9F\"><\/span>\n<p>  \u0647\u0648\u0646\u0648 \u0686\u06cc\u0633\u062a\u061f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Hono \u06cc\u06a9 \u0641\u0631\u06cc\u0645 \u0648\u0631\u06a9 \u0627\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u062a\u062d\u062a \u0648\u0628 \u0627\u0633\u062a \u06a9\u0647 \u0628\u0633\u06cc\u0627\u0631 \u0633\u0631\u06cc\u0639 \u0648 \u0633\u0628\u06a9 \u0627\u0633\u062a.  \u0627\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0631 \u0631\u0648\u06cc \u0647\u0631 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627 \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a \u06a9\u0627\u0631 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0634\u0627\u0645\u0644 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u062f\u0627\u062e\u0644\u06cc \u0648 \u06a9\u0645\u06a9 \u06a9\u0646\u0646\u062f\u0647 \u0627\u0633\u062a.  \u0627\u062c\u0631\u0627\u06cc \u0622\u0646 \u0634\u0628\u06cc\u0647 Express \u0627\u0633\u062a \u0648 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646 \u0631\u0627 \u0628\u0635\u0631\u06cc \u0645\u06cc \u06a9\u0646\u062f.  \u0647\u0645\u0686\u0646\u06cc\u0646 \u062f\u0627\u0631\u0627\u06cc \u06cc\u06a9 API \u062a\u0645\u06cc\u0632 \u0648 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u062f\u0631\u062c\u0647 \u06cc\u06a9 \u0627\u0632 TypeScript \u0627\u0633\u062a.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u062c\u0632\u0626\u06cc\u0627\u062a \u0628\u06cc\u0634\u062a\u0631\u060c \u0628\u0647 https:\/\/hono.dev\/ \u0645\u0631\u0627\u062c\u0639\u0647 \u06a9\u0646\u06cc\u062f<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Bun_%DA%86%DB%8C%D8%B3%D8%AA%D8%9F\"><\/span>\n<p>  Bun \u0686\u06cc\u0633\u062a\u061f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Bun \u06cc\u06a9 \u0632\u0645\u0627\u0646 \u0627\u062c\u0631\u0627 \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a \u0648 \u06cc\u06a9 \u062c\u0639\u0628\u0647 \u0627\u0628\u0632\u0627\u0631 \u0647\u0645\u0647 \u06a9\u0627\u0631\u0647 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a \u0648 \u062a\u0627\u06cc\u067e \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a \u0627\u0633\u062a.  \u0627\u06cc\u0646 \u062f\u0631 Zig \u0646\u0648\u0634\u062a\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a \u0648 \u0628\u0647 \u0635\u0648\u0631\u062a \u062f\u0627\u062e\u0644\u06cc \u0627\u0632 JavaScriptCore \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f\u060c \u06cc\u06a9 \u0645\u0648\u062a\u0648\u0631 JS \u0639\u0645\u0644\u06a9\u0631\u062f \u0645\u062d\u0648\u0631 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0633\u0627\u0641\u0627\u0631\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f\u0647 \u0627\u0633\u062a.  \u0647\u0645\u0686\u0646\u06cc\u0646 Node.js \u0648 Web API \u0631\u0627 \u0628\u0647 \u0635\u0648\u0631\u062a \u0628\u0648\u0645\u06cc \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u062a\u0645\u0627\u0645 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a\u060c \u0627\u0632 \u062c\u0645\u0644\u0647 \u0645\u062f\u06cc\u0631 \u0628\u0633\u062a\u0647\u060c \u0627\u062c\u0631\u0627\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634\u06cc \u0648 \u0628\u0627\u0646\u062f\u0644\u0631 \u0631\u0627 \u0641\u0631\u0627\u0647\u0645 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u062c\u0632\u0626\u06cc\u0627\u062a \u0628\u06cc\u0634\u062a\u0631 \u0628\u0647 \u0622\u062f\u0631\u0633 \u0632\u06cc\u0631 \u0645\u0631\u0627\u062c\u0639\u0647 \u06a9\u0646\u06cc\u062f: https:\/\/bun.sh\/<\/p>\n<h2><span class=\"ez-toc-section\" id=\"WebSocket_%DA%86%DB%8C%D8%B3%D8%AA%D8%9F\"><\/span>\n<p>  WebSocket \u0686\u06cc\u0633\u062a\u061f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>WebSocket \u067e\u0631\u0648\u062a\u06a9\u0644\u06cc \u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u06a9\u0627\u0646\u0627\u0644 \u0627\u0631\u062a\u0628\u0627\u0637\u06cc \u062f\u0648 \u0637\u0631\u0641\u0647 \u067e\u0627\u06cc\u062f\u0627\u0631 \u0628\u06cc\u0646 \u06cc\u06a9 \u0645\u0631\u0648\u0631\u06af\u0631 \u0648\u0628 \u0648 \u06cc\u06a9 \u0633\u0631\u0648\u0631 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f.  \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0627\u06cc\u0646 \u0641\u0646\u0627\u0648\u0631\u06cc\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u062f\u06cc \u0648\u0628 \u0645\u06cc \u062a\u0648\u0627\u0646\u0646\u062f \u062f\u0627\u062f\u0647 \u0647\u0627 \u0631\u0627 \u0628\u0647 \u0635\u0648\u0631\u062a \u0628\u0644\u0627\u062f\u0631\u0646\u06af \u0628\u0627 \u0633\u0631\u0648\u0631 \u0645\u0628\u0627\u062f\u0644\u0647 \u06a9\u0646\u0646\u062f\u060c \u0628\u062f\u0648\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u0634\u062a\u0631\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a HTTP \u062c\u062f\u06cc\u062f\u06cc \u0631\u0627 \u0622\u063a\u0627\u0632 \u06a9\u0646\u062f \u06cc\u0627 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0628\u0627\u0631\u06af\u0630\u0627\u0631\u06cc \u0645\u062c\u062f\u062f \u06a9\u0646\u062f.<\/p>\n<p>\u0639\u0645\u0644\u06cc\u0627\u062a WebSocket \u0627\u0632 \u0637\u0631\u06cc\u0642 \u0641\u0631\u0622\u06cc\u0646\u062f \u0632\u06cc\u0631 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u0634\u0648\u062f:<\/p>\n<p><strong>\u0634\u0631\u0648\u0639 \u062f\u0633\u062a \u062f\u0627\u062f\u0646<\/strong>: \u0645\u0634\u062a\u0631\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a HTTP \u0632\u06cc\u0631 \u0631\u0627 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0631\u062a\u0642\u0627\u0621 \u0627\u0632 HTTP \u0628\u0647 WebSocket \u0631\u0627 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>GET \/chat HTTP\/1.1\nHost: server.example.com\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\nOrigin: http:\/\/example.com\nSec-WebSocket-Protocol: chat, superchat\nSec-WebSocket-Version: 13\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><strong>\u067e\u0627\u0633\u062e \u0633\u0631\u0648\u0631<\/strong>: \u0627\u06af\u0631 \u0633\u0631\u0648\u0631 \u0627\u0632 WebSocket \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u06a9\u0646\u062f \u0648 \u0628\u0627 \u0627\u0631\u062a\u0642\u0627 \u0645\u0648\u0627\u0641\u0642\u062a \u06a9\u0646\u062f\u060c \u0633\u0631\u0648\u0631 \u0628\u0627 \u062f\u0633\u062a \u062f\u0627\u062f\u0646 \u062e\u0648\u062f \u067e\u0627\u0633\u062e \u0645\u06cc \u062f\u0647\u062f \u0648 \u062a\u063a\u06cc\u06cc\u0631 \u0628\u0647 \u067e\u0631\u0648\u062a\u06a9\u0644 WebSocket \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>HTTP\/1.1 101 Switching Protocols\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\nSec-WebSocket-Protocol: chat\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><strong>\u0627\u0646\u062a\u0642\u0627\u0644 \u062f\u0627\u062f\u0647<\/strong>: \u062f\u0631 \u062d\u06cc\u0646 \u062d\u0641\u0638 \u06cc\u06a9 \u0627\u062a\u0635\u0627\u0644 \u0628\u0627\u0632\u060c \u0633\u0631\u0648\u06cc\u0633 \u06af\u06cc\u0631\u0646\u062f\u0647 \u0648 \u0633\u0631\u0648\u0631 \u0645\u06cc \u062a\u0648\u0627\u0646\u0646\u062f \u062f\u0627\u062f\u0647 \u0647\u0627 \u0631\u0627 \u0645\u0628\u0627\u062f\u0644\u0647 \u06a9\u0646\u0646\u062f.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/media.dev.to\/cdn-cgi\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtz76azbqfd2zwy19in8.png\" alt=\"\u0646\u0645\u0648\u062f\u0627\u0631 WebSocket\" loading=\"lazy\" width=\"616\" height=\"526\" title=\"\"><\/p>\n<p>\u0627\u06cc\u0646 \u0646\u0645\u0648\u062f\u0627\u0631 \u062c\u0631\u06cc\u0627\u0646 \u0627\u0635\u0644\u06cc \u0627\u0631\u062a\u0628\u0627\u0637 WebSocket \u0628\u06cc\u0646 \u0645\u0634\u062a\u0631\u06cc \u0648 \u0633\u0631\u0648\u0631 \u0631\u0627 \u0646\u0634\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f.  \u0627\u0628\u062a\u062f\u0627\u060c \u06a9\u0644\u0627\u06cc\u0646\u062a \u0627\u0632 \u0637\u0631\u06cc\u0642 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a HTTP \u0627\u0632 \u0633\u0631\u0648\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0631\u062a\u0642\u0627\u0621 \u0628\u0647 WebSocket \u0631\u0627 \u0645\u06cc \u06a9\u0646\u062f.  \u0633\u067e\u0633\u060c \u0633\u0631\u0648\u0631 \u06cc\u06a9 \u067e\u0627\u0633\u062e HTTP \u0631\u0627 \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0627\u0646\u062f \u0648 \u0633\u0648\u0626\u06cc\u0686 \u067e\u0631\u0648\u062a\u06a9\u0644 \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u0645\u06cc\u200c\u06a9\u0646\u062f.  \u0627\u06cc\u0646 \u0627\u062a\u0635\u0627\u0644 \u0631\u0627 \u0628\u0627\u0632 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u06a9\u0644\u0627\u06cc\u0646\u062a \u0648 \u0633\u0631\u0648\u0631 \u0645\u06cc \u062a\u0648\u0627\u0646\u0646\u062f \u062f\u0627\u062f\u0647 \u0647\u0627 \u0631\u0627 \u0645\u0628\u0627\u062f\u0644\u0647 \u06a9\u0646\u0646\u062f.<\/p>\n<p>\u0645\u0646 \u0645\u06cc \u062e\u0648\u0627\u0647\u0645 \u0639\u0645\u06cc\u0642 \u062a\u0631 \u062f\u0631 \u0627\u06cc\u0646 \u0632\u0645\u06cc\u0646\u0647 \u06a9\u0627\u0648\u0634 \u06a9\u0646\u0645 \u062a\u0627 \u0622\u0646 \u0631\u0627 \u0628\u0647\u062a\u0631 \u062f\u0631\u06a9 \u06a9\u0646\u0645\u060c \u0627\u0645\u0627 \u0641\u0639\u0644\u0627 \u0647\u0645\u06cc\u0646 \u0627\u0633\u062a.<\/p>\n<p>\u0646\u0645\u0648\u0646\u0647 \u0647\u0627\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0648 \u067e\u0627\u0633\u062e \u0628\u0631\u0627\u06cc \u062f\u0633\u062a \u062f\u0627\u062f\u0646 \u0627\u0632 RFC \u0646\u0642\u0644 \u0634\u062f\u0647 \u0627\u0633\u062a.<br \/>https:\/\/datatracker.ietf.org\/doc\/html\/rfc6455#section-1.2<\/p>\n<h2><span class=\"ez-toc-section\" id=\"%D9%BE%DB%8C%D8%A7%D8%AF%D9%87_%D8%B3%D8%A7%D8%B2%DB%8C\"><\/span>\n<p>  \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0628\u0627 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0642\u0637\u0639\u0627\u062a \u0627\u0632 \u0627\u06cc\u0646 \u0645\u062e\u0632\u0646 \u0628\u0631 \u0631\u0648\u06cc \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0647\u0627\u06cc \u06a9\u0644\u06cc\u062f\u06cc \u062a\u0645\u0631\u06a9\u0632 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f.  \u0645\u0646 \u0645\u06cc \u062e\u0648\u0627\u0647\u0645 \u062a\u0627 \u062d\u062f \u0627\u0645\u06a9\u0627\u0646 \u062a\u0648\u0636\u06cc\u062d \u062f\u0647\u0645\u060c \u0627\u0632 \u062c\u0645\u0644\u0647 \u0648\u0627\u0631\u062f\u0627\u062a \u0648\u0627\u0628\u0633\u062a\u06af\u06cc \u0647\u0627 \u0648 \u062a\u0639\u0631\u06cc\u0641 \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0628\u062e\u0634 \u0647\u0627\u06cc\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f \u06a9\u0647 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0648\u0627\u0642\u0639\u06cc \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 \u0628\u0627\u0632\u0646\u0648\u06cc\u0633\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.  \u0627\u06af\u0631 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u062c\u0632\u0626\u06cc\u0627\u062a \u0631\u0627 \u062f\u0631\u06a9 \u06a9\u0646\u06cc\u062f\u060c \u0644\u0637\u0641\u0627\u064b \u06a9\u062f \u0645\u0646\u0628\u0639 \u0645\u062e\u0632\u0646 \u0631\u0627 \u0628\u0647 \u0637\u0648\u0631 \u0645\u0648\u0627\u0632\u06cc \u0628\u062e\u0648\u0627\u0646\u06cc\u062f \u0648 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0631\u0627 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u06a9\u0645\u0644 \u062f\u0631 \u0646\u0638\u0631 \u0628\u06af\u06cc\u0631\u06cc\u062f.<\/p>\n<p>\u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0628\u0631\u0646\u0627\u0645\u0647 \u062a\u06a9\u0645\u06cc\u0644 \u0634\u062f\u0647 \u0631\u0627 \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u062f: https:\/\/github.com\/yutakusuno\/bun-hono-react-websocket<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Backend_%D9%BE%DB%8C%DA%A9%D8%B1%D8%A8%D9%86%D8%AF%DB%8C_WebSocket\"><\/span>\n<p>  Backend: \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc WebSocket<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>server\/index.ts<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Hono<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">hono<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">createBunWebSocket<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">hono\/bun<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">app<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Hono<\/span><span class=\"p\">();<\/span>\n<span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">upgradeWebSocket<\/span><span class=\"p\">,<\/span> <span class=\"nx\">websocket<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">createBunWebSocket<\/span><span class=\"p\">();<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">server<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">Bun<\/span><span class=\"p\">.<\/span><span class=\"nf\">serve<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">fetch<\/span><span class=\"p\">:<\/span> <span class=\"nx\">app<\/span><span class=\"p\">.<\/span><span class=\"nx\">fetch<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">port<\/span><span class=\"p\">:<\/span> <span class=\"mi\">3000<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">websocket<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"nx\">app<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0647\u0646\u06af\u0627\u0645 \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc \u06cc\u06a9 \u0633\u0631\u0648\u0631 HTTP \u0628\u0627 Bun\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u0634\u0648\u062f <code>Bun.serve<\/code>.  \u0646\u0645\u0648\u0646\u0647 \u0627\u06cc \u0627\u0632 \u06a9\u0644\u0627\u0633 Hono \u0631\u0627 \u0628\u0647 \u0627\u06cc\u0646 \u06a9\u0646\u062a\u0631\u0644 \u06a9\u0646\u0646\u062f\u0647 \u0648\u0627\u06a9\u0634\u06cc \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u062f \u0648 \u067e\u0648\u0631\u062a \u0633\u0631\u0648\u0631 \u0628\u0627\u0637\u0646 \u0631\u0627 \u0645\u0634\u062e\u0635 \u06a9\u0646\u06cc\u062f.  \u0633\u0648\u06a9\u062a \u0648\u0628 \u0648\u0627\u0631\u062f \u0634\u062f\u0647 \u0627\u0632 <code>createBunWebSocket<\/code> \u06cc\u06a9 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 Hono\u060c \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u0646\u062f\u0647 WebSocket \u0627\u0633\u062a \u06a9\u0647 \u0628\u0631\u0627\u06cc Bun \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Backend_%D8%A7%D8%AA%D8%B5%D8%A7%D9%84_%D9%88_%D9%82%D8%B7%D8%B9_%D8%A7%D8%AA%D8%B5%D8%A7%D9%84_WebSocket\"><\/span>\n<p>  Backend: \u0627\u062a\u0635\u0627\u0644 \u0648 \u0642\u0637\u0639 \u0627\u062a\u0635\u0627\u0644 WebSocket<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>server\/index.ts<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"kd\">type<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">ServerWebSocket<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">bun<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">topic<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">anonymous-chat-room<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"nx\">app<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span>\n  <span class=\"dl\">'<\/span><span class=\"s1\">\/ws<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n  <span class=\"nf\">upgradeWebSocket<\/span><span class=\"p\">((<\/span><span class=\"nx\">_<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">({<\/span>\n    <span class=\"nf\">onOpen<\/span><span class=\"p\">(<\/span><span class=\"nx\">_<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ws<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">rawWs<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">ws<\/span><span class=\"p\">.<\/span><span class=\"nx\">raw<\/span> <span class=\"k\">as<\/span> <span class=\"nx\">ServerWebSocket<\/span><span class=\"p\">;<\/span>\n      <span class=\"nx\">rawWs<\/span><span class=\"p\">.<\/span><span class=\"nf\">subscribe<\/span><span class=\"p\">(<\/span><span class=\"nx\">topic<\/span><span class=\"p\">);<\/span>\n      <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"s2\">`WebSocket server opened and subscribed to topic '<\/span><span class=\"p\">${<\/span><span class=\"nx\">topic<\/span><span class=\"p\">}<\/span><span class=\"s2\">'`<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">},<\/span>\n    <span class=\"nf\">onClose<\/span><span class=\"p\">(<\/span><span class=\"nx\">_<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ws<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">rawWs<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">ws<\/span><span class=\"p\">.<\/span><span class=\"nx\">raw<\/span> <span class=\"k\">as<\/span> <span class=\"nx\">ServerWebSocket<\/span><span class=\"p\">;<\/span>\n      <span class=\"nx\">rawWs<\/span><span class=\"p\">.<\/span><span class=\"nf\">unsubscribe<\/span><span class=\"p\">(<\/span><span class=\"nx\">topic<\/span><span class=\"p\">);<\/span>\n      <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span>\n        <span class=\"s2\">`WebSocket server closed and unsubscribed from topic '<\/span><span class=\"p\">${<\/span><span class=\"nx\">topic<\/span><span class=\"p\">}<\/span><span class=\"s2\">'`<\/span>\n      <span class=\"p\">);<\/span>\n    <span class=\"p\">},<\/span>\n  <span class=\"p\">}))<\/span>\n<span class=\"p\">);<\/span>\n\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0631\u0641\u062a\u0627\u0631 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u06cc\u06a9 \u0627\u062a\u0635\u0627\u0644 WebSocket \u0628\u0627\u0632 \u0648 \u0628\u0633\u062a\u0647 \u0645\u06cc \u0634\u0648\u062f\u060c \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc \u0634\u0648\u062f.  \u0647\u0646\u06af\u0627\u0645\u06cc \u06a9\u0647 \u06cc\u06a9 \u0627\u062a\u0635\u0627\u0644 \u0628\u0627\u0632 \u0645\u06cc \u0634\u0648\u062f\u060c \u0634\u0631\u0648\u0639 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u062f\u0631 \u06cc\u06a9 \u0645\u0648\u0636\u0648\u0639 \u062e\u0627\u0635 \u0645\u06cc \u06a9\u0646\u062f <code>synonymous-chat-room<\/code>\u060c \u0648 \u0647\u0646\u06af\u0627\u0645\u06cc \u06a9\u0647 \u06cc\u06a9 \u0627\u062a\u0635\u0627\u0644 \u0628\u0633\u062a\u0647 \u0645\u06cc \u0634\u0648\u062f\u060c \u0628\u0647 \u0622\u0646 \u0627\u0634\u062a\u0631\u0627\u06a9 \u067e\u0627\u06cc\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f.  \u062f\u0631 \u0627\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647\u060c \u0648\u0642\u062a\u06cc \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0646\u0627\u0634\u0646\u0627\u0633 \u0635\u0641\u062d\u0647 \u0627\u06cc \u0631\u0627 \u0628\u0627\u0632 \u0645\u06cc \u06a9\u0646\u062f\u060c \u06cc\u06a9 \u0627\u0631\u062a\u0628\u0627\u0637 WebSocket \u0628\u0631\u0642\u0631\u0627\u0631 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0634\u0631\u0648\u0639 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u062f\u0631 \u0645\u0648\u0636\u0648\u0639 \u0645\u06cc \u06a9\u0646\u062f.  \u0627\u06cc\u0646 \u0628\u0627\u0631 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a\u06cc \u0628\u0631\u0627\u06cc \u062a\u0639\u062f\u0627\u062f \u0627\u0641\u0631\u0627\u062f\u06cc \u06a9\u0647 \u0645\u06cc \u062a\u0648\u0627\u0646\u0646\u062f \u062f\u0631 \u06cc\u06a9 \u0645\u0648\u0636\u0648\u0639 \u0645\u0634\u062a\u0631\u06a9 \u0634\u0648\u0646\u062f \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u062f.<\/p>\n<p>\u0627\u0634\u062a\u0631\u0627\u06a9 \u062f\u0631 \u0645\u0648\u0636\u0648\u0639\u0627\u062a \u0628\u0647 \u0637\u0648\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 \u062f\u0631 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc Hono \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0646\u0645\u06cc \u0634\u0648\u062f\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0628\u0627\u06cc\u062f \u0627\u0632 Bun \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645 <code>ServerWebSocket<\/code>.  \u0628\u0647 \u0637\u0648\u0631 \u062e\u0627\u0635\u060c \u0627\u06cc\u0646 \u0627\u0645\u0631 \u0628\u0627 \u06af\u0633\u062a\u0631\u0634 \u062f\u0627\u062f\u0646 \u0628\u0647 \u062f\u0633\u062a \u0645\u06cc \u0622\u06cc\u062f <code>ws<\/code> \u06a9\u0647 \u062f\u0631 <code>onOpen<\/code>.  \u0628\u0627 \u0646\u06af\u0627\u0647\u06cc \u0628\u0647 \u06a9\u062f \u0645\u0646\u0628\u0639 Hono\u060c <code>ws.raw<\/code> WebSocket \u0633\u0631\u0648\u0631 Bun \u0627\u0633\u062a \u0648 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u0645 WebSocket \u0628\u0648\u0645\u06cc Bun \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0631\u062f\u0647 \u0648 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0645\u0648\u0636\u0648\u0639 \u0631\u0627 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u0645.  \u0646\u0627\u0645 \u0647\u0631 \u0645\u0648\u0636\u0648\u0639\u06cc \u0631\u0627 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u0631\u0634\u062a\u0647 \u0628\u0631\u0627\u06cc \u0627\u0634\u062a\u0631\u0627\u06a9 \u0648 \u0644\u063a\u0648 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0627\u0631\u0633\u0627\u0644 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc Bun WebSocket \u062a\u0648\u0633\u0637 Hono:<br \/>https:\/\/github.com\/honojs\/hono\/blob\/main\/src\/adapter\/bun\/websocket.ts<\/p>\n<p>\u0627\u0633\u0646\u0627\u062f \u0631\u0633\u0645\u06cc \u0628\u0631\u0627\u06cc Bun WebSocket:<br \/>https:\/\/bun.sh\/docs\/api\/websockets<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Backend_messages_Endpoint\"><\/span>\n<p>  Backend: \/messages Endpoint<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>server\/index.ts<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">zValidator<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">@hono\/zod-validator<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">messagesRoute<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">app<\/span>\n  <span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">\/messages<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">c<\/span><span class=\"p\">.<\/span><span class=\"nf\">json<\/span><span class=\"p\">(<\/span><span class=\"nx\">messages<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"p\">.<\/span><span class=\"nf\">post<\/span><span class=\"p\">(<\/span>\n    <span class=\"dl\">'<\/span><span class=\"s1\">\/messages<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n    <span class=\"nf\">zValidator<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">form<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">MessageFormSchema<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">result<\/span><span class=\"p\">,<\/span> <span class=\"nx\">c<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">result<\/span><span class=\"p\">.<\/span><span class=\"nx\">success<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nx\">c<\/span><span class=\"p\">.<\/span><span class=\"nf\">json<\/span><span class=\"p\">({<\/span> <span class=\"na\">ok<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span> <span class=\"p\">},<\/span> <span class=\"mi\">400<\/span><span class=\"p\">);<\/span>\n      <span class=\"p\">}<\/span>\n    <span class=\"p\">}),<\/span>\n    <span class=\"k\">async <\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">param<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">c<\/span><span class=\"p\">.<\/span><span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nf\">valid<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">form<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">currentDateTime<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Date<\/span><span class=\"p\">();<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"na\">message<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Message<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n        <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Number<\/span><span class=\"p\">(<\/span><span class=\"nx\">currentDateTime<\/span><span class=\"p\">),<\/span>\n        <span class=\"na\">date<\/span><span class=\"p\">:<\/span> <span class=\"nx\">currentDateTime<\/span><span class=\"p\">.<\/span><span class=\"nf\">toLocaleString<\/span><span class=\"p\">(),<\/span>\n        <span class=\"p\">...<\/span><span class=\"nx\">param<\/span><span class=\"p\">,<\/span>\n      <span class=\"p\">};<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"nx\">DataToSend<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n        <span class=\"na\">action<\/span><span class=\"p\">:<\/span> <span class=\"nx\">publishActions<\/span><span class=\"p\">.<\/span><span class=\"nx\">UPDATE_CHAT<\/span><span class=\"p\">,<\/span>\n        <span class=\"na\">message<\/span><span class=\"p\">:<\/span> <span class=\"nx\">message<\/span><span class=\"p\">,<\/span>\n      <span class=\"p\">};<\/span>\n\n      <span class=\"nx\">server<\/span><span class=\"p\">.<\/span><span class=\"nf\">publish<\/span><span class=\"p\">(<\/span><span class=\"nx\">topic<\/span><span class=\"p\">,<\/span> <span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">stringify<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">));<\/span>\n\n      <span class=\"k\">return<\/span> <span class=\"nx\">c<\/span><span class=\"p\">.<\/span><span class=\"nf\">json<\/span><span class=\"p\">({<\/span> <span class=\"na\">ok<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span> <span class=\"p\">});<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">)<\/span>\n  <span class=\"p\">.<\/span><span class=\"k\">delete<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">\/messages\/:id<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ Logic of message deletion<\/span>\n  <span class=\"p\">});<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">type<\/span> <span class=\"nx\">AppType<\/span> <span class=\"o\">=<\/span> <span class=\"k\">typeof<\/span> <span class=\"nx\">messagesRoute<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0627\u06cc\u0646 \u0645\u0646\u0628\u0639 \u067e\u06cc\u0627\u0645 \u0627\u0632 \u0631\u0648\u0634 \u0647\u0627\u06cc GET\u060c POST\u060c DELETE \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0645\u06cc \u06a9\u0646\u062f.  \u0645\u062a\u062f GET \u062a\u0627\u0631\u06cc\u062e\u0686\u0647 \u067e\u06cc\u0627\u0645 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u0634\u062a\u0631\u06a9 \u062f\u0631 \u06cc\u06a9 \u0645\u0648\u0636\u0648\u0639 \u0631\u0627 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u0645\u06cc \u06a9\u0646\u062f\u060c \u0631\u0648\u0634 POST \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u062c\u062f\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0631\u0648\u0634 DELETE \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u062e\u0627\u0635 \u0631\u0627 \u062d\u0630\u0641 \u0645\u06cc \u06a9\u0646\u062f.  \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627\u060c \u0645\u0646 \u0628\u0631 \u062a\u0648\u0636\u06cc\u062d POST \/messages \u062a\u0645\u0631\u06a9\u0632 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f.<\/p>\n<p>\u0646\u0645\u0648\u0646\u0647 \u0633\u0631\u0648\u0631 \u0647\u0646\u06af\u0627\u0645 \u0627\u06cc\u062c\u0627\u062f \u0633\u0631\u0648\u0631 Bun \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062f\u0631 \u0627\u06cc\u0646 \u0646\u0642\u0637\u0647 \u067e\u0627\u06cc\u0627\u0646\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f.  \u0628\u0627 \u062a\u0645\u0627\u0633 <code>publish()<\/code> \u0628\u0631 \u0631\u0648\u06cc <code>server<\/code> \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u0645\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u0645 \u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u0645\u0634\u062a\u0631\u06cc\u0627\u0646\u06cc \u06a9\u0647 \u062f\u0631 \u06cc\u06a9 \u0645\u0648\u0636\u0648\u0639 \u0645\u0634\u062a\u0631\u06a9 \u0647\u0633\u062a\u0646\u062f\u060c \u067e\u062e\u0634 \u06a9\u0646\u06cc\u0645.  \u0637\u0628\u0642 \u0633\u0646\u062f \u0631\u0633\u0645\u06cc \u0627\u0645\u06a9\u0627\u0646 \u067e\u062e\u0634 \u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u0645\u0634\u062a\u0631\u06a9\u06cc\u0646 \u062a\u0627\u067e\u06cc\u06a9 \u0628\u0647 \u0627\u0633\u062a\u062b\u0646\u0627\u06cc \u0633\u0648\u06a9\u062a\u06cc \u06a9\u0647 \u0628\u0647 \u0646\u0627\u0645 <code>publish()<\/code>\u060c \u0627\u0645\u0627 \u0627\u06cc\u0646 \u0628\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc \u0634\u0648\u062f.<\/p>\n<p>\u0647\u0645\u0686\u0646\u06cc\u0646\u060c \u0645\u0627\u0646\u0646\u062f Express\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u0642\u0628\u0644 \u0627\u0632 \u067e\u0631\u062f\u0627\u0632\u0634 \u0645\u0646\u0637\u0642 \u0645\u0646\u0628\u0639\u060c \u0645\u06cc\u0627\u0646\u200c\u0627\u0641\u0632\u0627\u0631 \u0631\u0627 \u0628\u0627 \u0639\u0628\u0648\u0631 \u0627\u0632 \u06cc\u06a9 handler \u062f\u0631 \u0646\u0642\u0637\u0647 \u067e\u0627\u06cc\u0627\u0646\u06cc \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u0645.  \u0627\u06cc\u0646 \u0628\u062e\u0634\u06cc \u0627\u0632 <code>zValidator<\/code>.  \u0627\u06cc\u0646 \u0628\u0647 \u0645\u0627 \u0627\u06cc\u0646 \u0627\u0645\u06a9\u0627\u0646 \u0631\u0627 \u0645\u06cc \u062f\u0647\u062f \u06a9\u0647 \u0631\u0633\u06cc\u062f\u06af\u06cc \u06a9\u0646\u06cc\u0645 <code>param<\/code> \u0628\u0647 \u0631\u0648\u0634\u06cc \u0627\u06cc\u0645\u0646 \u0627\u0632 \u0646\u0638\u0631 \u0646\u0648\u0639<\/p>\n<p>\u06a9\u0647 \u062f\u0631 <code>type AppType<\/code>\u060c \u0646\u0648\u0639 API \u062a\u0639\u0631\u06cc\u0641 \u0634\u062f\u0647 \u062f\u0631 <code>messagesRoute<\/code> \u0635\u0627\u062f\u0631 \u0645\u06cc \u0634\u0648\u062f.  \u0627\u06cc\u0646 \u062f\u0631 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc RPC \u062f\u0631 \u0641\u0631\u0627\u0646\u062a \u0627\u0646\u062f \u06a9\u0647 \u0628\u0639\u062f\u0627\u064b \u062a\u0648\u0636\u06cc\u062d \u062f\u0627\u062f\u0647 \u0634\u062f\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.  \u0628\u0627 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u06af\u0630\u0627\u0634\u062a\u0646 \u0645\u0634\u062e\u0635\u0627\u062a API \u0628\u0627 \u0645\u0634\u062a\u0631\u06cc\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u0628\u0647 \u06cc\u06a9 \u0627\u062c\u0631\u0627\u06cc API \u0627\u06cc\u0645\u0646 \u0627\u0632 \u0646\u0648\u0639 \u062f\u0633\u062a \u06cc\u0627\u0628\u06cc\u0645.<\/p>\n<p>shared\/types.ts<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">z<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">zod<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">MessageFormSchema<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">object<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">userId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">string<\/span><span class=\"p\">().<\/span><span class=\"nf\">min<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">),<\/span>\n  <span class=\"na\">text<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">string<\/span><span class=\"p\">().<\/span><span class=\"nf\">trim<\/span><span class=\"p\">().<\/span><span class=\"nf\">min<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">),<\/span>\n<span class=\"p\">});<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0645\u0646 \u0627\u0632 zod \u0628\u0631\u0627\u06cc <code>MessageFormSchema<\/code>.  \u0628\u0627 \u062a\u0631\u06a9\u06cc\u0628 TypeScript \u0648 zod \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u0645 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u062f\u0642\u06cc\u0642\u200c\u062a\u0631\u06cc \u0631\u0627 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u0645.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Frontend_%D8%B1%D8%A7%D9%87_%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C_WebSocket\"><\/span>\n<p>  Frontend: \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc WebSocket<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>frontend\/src\/App.tsx<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">messages<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setMessages<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Message<\/span><span class=\"p\">[]<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">([]);<\/span>\n\n<span class=\"nf\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">socket<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">WebSocket<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">ws:\/\/localhost:3000\/ws<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n\n  <span class=\"nx\">socket<\/span><span class=\"p\">.<\/span><span class=\"nx\">onopen<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">WebSocket client opened<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">event<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">};<\/span>\n\n  <span class=\"nx\">socket<\/span><span class=\"p\">.<\/span><span class=\"nx\">onmessage<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"na\">data<\/span><span class=\"p\">:<\/span> <span class=\"nx\">DataToSend<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">parse<\/span><span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nf\">toString<\/span><span class=\"p\">());<\/span>\n      <span class=\"k\">switch <\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">action<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">case<\/span> <span class=\"nx\">publishActions<\/span><span class=\"p\">.<\/span><span class=\"na\">UPDATE_CHAT<\/span><span class=\"p\">:<\/span>\n          <span class=\"nf\">setMessages<\/span><span class=\"p\">((<\/span><span class=\"nx\">prev<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[...<\/span><span class=\"nx\">prev<\/span><span class=\"p\">,<\/span> <span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">message<\/span><span class=\"p\">]);<\/span>\n          <span class=\"k\">break<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">case<\/span> <span class=\"nx\">publishActions<\/span><span class=\"p\">.<\/span><span class=\"na\">DELETE_CHAT<\/span><span class=\"p\">:<\/span>\n          <span class=\"nf\">setMessages<\/span><span class=\"p\">((<\/span><span class=\"nx\">prev<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span>\n            <span class=\"nx\">prev<\/span><span class=\"p\">.<\/span><span class=\"nf\">filter<\/span><span class=\"p\">((<\/span><span class=\"nx\">message<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">)<\/span>\n          <span class=\"p\">);<\/span>\n          <span class=\"k\">break<\/span><span class=\"p\">;<\/span>\n        <span class=\"nl\">default<\/span><span class=\"p\">:<\/span>\n          <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">Unknown data:<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n      <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">_<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">Message from server:<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">event<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">};<\/span>\n  <span class=\"nx\">socket<\/span><span class=\"p\">.<\/span><span class=\"nx\">onclose<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">WebSocket client closed<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">event<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">};<\/span>\n\n  <span class=\"k\">return <\/span><span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">socket<\/span><span class=\"p\">.<\/span><span class=\"nf\">close<\/span><span class=\"p\">();<\/span>\n  <span class=\"p\">};<\/span>\n<span class=\"p\">},<\/span> <span class=\"p\">[]);<\/span>\n\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0645\u0646 \u06cc\u06a9 \u0633\u0631\u0648\u06cc\u0633 \u06af\u06cc\u0631\u0646\u062f\u0647 WebSocket \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u0645 \u0648 \u0622\u0646 \u0631\u0627 \u0628\u0647 \u0633\u0631\u0648\u0631 \u0645\u062a\u0635\u0644 \u0645\u06cc \u06a9\u0646\u0645.  \u0645\u0646 \u0631\u0641\u062a\u0627\u0631 \u0631\u0627 \u0628\u0631\u0627\u06cc \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0627\u062a\u0635\u0627\u0644 WebSocket \u0628\u0627\u0632 \u0645\u06cc \u0634\u0648\u062f\u060c \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc \u0634\u0648\u062f \u0648 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0627\u062a\u0635\u0627\u0644 \u0628\u0633\u062a\u0647 \u0645\u06cc \u0634\u0648\u062f\u060c \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc \u06a9\u0646\u0645.  \u06a9\u0647 \u062f\u0631 <code>socket.onmessage<\/code>\u060c \u0645\u0646 \u0627\u0632 \u06cc\u06a9 \u062f\u0633\u062a\u0648\u0631 switch \u0628\u0631\u0627\u06cc \u0627\u0646\u0634\u0639\u0627\u0628 \u0628\u0631 \u0627\u0633\u0627\u0633 \u0646\u0648\u0639 \u0639\u0645\u0644 \u062f\u0631\u06cc\u0627\u0641\u062a \u0634\u062f\u0647 \u0627\u0632 backend \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0645.  \u0627\u06cc\u0646 \u0628\u0647 \u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u062a\u0627 \u0645\u0648\u0627\u0631\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u062e\u062a\u0644\u0641 \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u0645.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ shared\/constants.ts<\/span>\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">publishActions<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">UPDATE_CHAT<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">UPDATE_CHAT<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">DELETE_CHAT<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">DELETE_CHAT<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">as<\/span> <span class=\"kd\">const<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">\/\/ shared\/types.ts<\/span>\n<span class=\"kd\">type<\/span> <span class=\"nx\">PublishAction<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"k\">typeof<\/span> <span class=\"nx\">publishActions<\/span><span class=\"p\">)[<\/span><span class=\"kr\">keyof<\/span> <span class=\"k\">typeof<\/span> <span class=\"nx\">publishActions<\/span><span class=\"p\">];<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">type<\/span> <span class=\"nx\">Message<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span> <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"kr\">number<\/span><span class=\"p\">;<\/span> <span class=\"nl\">date<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span> <span class=\"p\">}<\/span> <span class=\"o\">&amp;<\/span> <span class=\"nx\">MessageFormValues<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">type<\/span> <span class=\"nx\">DataToSend<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">action<\/span><span class=\"p\">:<\/span> <span class=\"nx\">PublishAction<\/span><span class=\"p\">;<\/span>\n  <span class=\"nl\">message<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Message<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u062b\u0627\u0628\u062a \u0647\u0627 \u0648 \u062a\u0639\u0627\u0631\u06cc\u0641 \u0646\u0648\u0639 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u062f\u0647 \u0628\u0631\u0627\u06cc WebSocket \u0648 \u0645\u062f\u06cc\u0631\u06cc\u062a \u067e\u06cc\u0627\u0645 \u0622\u0648\u0631\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a.  \u0627\u06cc\u0646 <code>PublishAction type<\/code> \u0645\u062c\u0645\u0648\u0639 \u0645\u0642\u0627\u062f\u06cc\u0631 the \u0631\u0627 \u0627\u0633\u062a\u0646\u0628\u0627\u0637 \u0645\u06cc \u06a9\u0646\u062f <code>publishActions<\/code> \u0634\u06cc \u0648 \u0646\u0648\u0639 \u0634\u0645\u0627\u0631\u0634 \u0631\u0627 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Frontend_%D8%A7%D8%B1%D8%B3%D8%A7%D9%84_%D9%BE%DB%8C%D8%A7%D9%85\"><\/span>\n<p>  Frontend: \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>frontend\/src\/App.tsx<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">hc<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">hono\/client<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"kd\">type<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">AppType<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">@server\/index<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">honoClient<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">hc<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">AppType<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">http:\/\/localhost:3000<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">handleSubmit<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async <\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">:<\/span> <span class=\"nx\">FormEvent<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">HTMLFormElement<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nf\">preventDefault<\/span><span class=\"p\">();<\/span>\n  <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"nx\">validatedValues<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">MessageFormSchema<\/span><span class=\"p\">.<\/span><span class=\"nf\">parse<\/span><span class=\"p\">(<\/span><span class=\"nx\">formValues<\/span><span class=\"p\">);<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"nx\">response<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">honoClient<\/span><span class=\"p\">.<\/span><span class=\"nx\">messages<\/span><span class=\"p\">.<\/span><span class=\"nf\">$post<\/span><span class=\"p\">({<\/span>\n      <span class=\"na\">form<\/span><span class=\"p\">:<\/span> <span class=\"nx\">validatedValues<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">});<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">ok<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Error<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">Failed to send message<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n  <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ Error Handling Logic<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">};<\/span>\n\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u06a9\u0647 \u062f\u0631 <code>handleSubmit<\/code>\u060c \u0645\u0646 \u0645\u0646\u0637\u0642 \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645 \u062c\u062f\u06cc\u062f \u0631\u0627 \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc \u06a9\u0646\u0645.  \u0647\u0646\u06af\u0627\u0645\u06cc \u06a9\u0647 \u0645\u062a\u0646 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc \u0634\u0648\u062f\u060c \u0645\u0642\u062f\u0627\u0631 \u0648\u0631\u0648\u062f\u06cc \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u0645\u06cc \u06a9\u0646\u062f \u0648 \u067e\u06cc\u0627\u0645 \u062c\u062f\u06cc\u062f \u0631\u0627 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a POST \u0628\u0647 \u0633\u0631\u0648\u0631 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>\u0646\u06a9\u062a\u0647 \u0642\u0627\u0628\u0644 \u062a\u0648\u062c\u0647 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0645\u0646 \u0627\u0632 \u0645\u0634\u062a\u0631\u06cc Hono \u0628\u0647 \u062c\u0627\u06cc fetch API \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0645.  \u0645\u0646 \u0645\u0634\u062e\u0635 \u0645\u06cc \u06a9\u0646\u0645 <code>AppType<\/code> \u062f\u0631 backend \u0648 URL backend \u0628\u0647 \u0635\u0627\u062f\u0631 \u0645\u06cc \u0634\u0648\u062f <code>hc<\/code>\u060c \u0648 \u06cc\u06a9 type-safe \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0646\u06cc\u062f <code>honoClient<\/code>.  \u0627\u06cc\u0646 \u0627\u0645\u06a9\u0627\u0646 \u0627\u062c\u0631\u0627\u06cc RPC \u0631\u0627 \u0641\u0631\u0627\u0647\u0645 \u0645\u06cc \u06a9\u0646\u062f.  \u06af\u06cc\u0641 \u0632\u06cc\u0631 \u0646\u0645\u0627\u06cc\u0634\u06cc \u0627\u0632 TypeScript \u0627\u0633\u062a \u06a9\u0647 \u0647\u0646\u06af\u0627\u0645 \u0627\u0631\u0633\u0627\u0644 \u0645\u0642\u062f\u0627\u0631 \u0646\u0627\u062f\u0631\u0633\u062a \u0646\u0648\u0639 \u062f\u0627\u062f\u0647\u060c \u062e\u0637\u0627\u06cc \u06a9\u0627\u0645\u067e\u0627\u06cc\u0644 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f. <code>$post<\/code>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/media.dev.to\/cdn-cgi\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouwgw6mjj6nx8vosmlzq.gif\" alt=\"RPC Gif\" loading=\"lazy\" width=\"600\" height=\"338\" data-animated=\"true\" title=\"\"><\/p>\n<p>\u0627\u06cc\u0646 \u0628\u0647 \u0645\u0627 \u0627\u06cc\u0646 \u0627\u0645\u06a9\u0627\u0646 \u0631\u0627 \u0645\u06cc\u200c\u062f\u0647\u062f \u062a\u0627 \u0628\u0627 \u062a\u0631\u06a9\u06cc\u0628 \u06a9\u0631\u062f\u0646\u060c \u06cc\u06a9 API \u0627\u06cc\u0645\u0646 \u062a\u0627\u06cc\u067e \u0631\u0627 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u0645 <code>zod<\/code> \u0648 RPC<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"o\">&lt;<\/span><span class=\"nx\">form<\/span>\n  <span class=\"nx\">method<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">post<\/span><span class=\"dl\">\"<\/span>\n  <span class=\"nx\">onSubmit<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">handleSubmit<\/span><span class=\"p\">}<\/span>\n  <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">flex items-center space-x-2<\/span><span class=\"dl\">\"<\/span>\n<span class=\"o\">&gt;<\/span>\n  <span class=\"o\">&lt;<\/span><span class=\"nx\">input<\/span> <span class=\"nx\">name<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">userId<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">defaultValue<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">formValues<\/span><span class=\"p\">.<\/span><span class=\"nx\">userId<\/span><span class=\"p\">}<\/span> <span class=\"nx\">hidden<\/span> <span class=\"o\">\/&gt;<\/span>\n  <span class=\"o\">&lt;<\/span><span class=\"nx\">input<\/span>\n    <span class=\"nx\">name<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">text<\/span><span class=\"dl\">\"<\/span>\n    <span class=\"nx\">value<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">formValues<\/span><span class=\"p\">.<\/span><span class=\"nx\">text<\/span><span class=\"p\">}<\/span>\n    <span class=\"nx\">onChange<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">handleInputChange<\/span><span class=\"p\">}<\/span>\n    <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">flex-grow p-2 border border-gray-800 rounded-md bg-gray-800 text-white<\/span><span class=\"dl\">\"<\/span>\n  <span class=\"o\">\/&gt;<\/span>\n  <span class=\"o\">&lt;<\/span><span class=\"nx\">button<\/span>\n    <span class=\"kd\">type<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">submit<\/span><span class=\"dl\">\"<\/span>\n    <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">px-4 py-2 bg-blue-500 text-white rounded-md<\/span><span class=\"dl\">\"<\/span>\n  <span class=\"o\">&gt;<\/span>\n    <span class=\"nx\">Send<\/span>\n  <span class=\"o\">&lt;<\/span><span class=\"sr\">\/button<\/span><span class=\"err\">&gt;\n<\/span><span class=\"o\">&lt;<\/span><span class=\"sr\">\/form<\/span><span class=\"err\">&gt;\n<\/span><\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc UI \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0628\u062e\u0634 \u0641\u0631\u0645 \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0645\u06cc \u0634\u0648\u062f.  \u0627\u06cc\u0646 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u0633\u0627\u062f\u0647 \u0627\u0633\u062a\u060c \u0642\u0631\u0627\u0631 \u062f\u0627\u062f\u0646 \u06cc\u06a9 \u067e\u06cc\u0627\u0645 <code>input<\/code> \u0628\u0631\u0686\u0633\u0628 \u0648 \u06cc\u06a9 \u062f\u06a9\u0645\u0647 \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645 \u062f\u0631 \u062f\u0627\u062e\u0644 <code>form<\/code> \u0628\u0631\u0686\u0633\u0628 \u0632\u062f\u0646  \u0647\u0646\u06af\u0627\u0645\u06cc \u06a9\u0647 \u062f\u06a9\u0645\u0647 \u0627\u0631\u0633\u0627\u0644 \u0641\u0634\u0627\u0631 \u062f\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f\u060c <code>handleSubmit<\/code> \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc \u0645\u06cc \u0634\u0648\u062f \u0648 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u0647 \u0628\u0627\u0637\u0646 \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<p>\u0627\u06cc\u0646 \u0645\u0642\u062f\u0645\u0647 \u0627\u062c\u0631\u0627\u06cc \u0627\u0635\u0644\u06cc \u0627\u0633\u062a.  \u0634\u062e\u0635\u0627\u064b \u0645\u062a\u0648\u062c\u0647 \u0634\u062f\u0645 \u06a9\u0647 \u0631\u0627\u0647\u200c\u0627\u0646\u062f\u0627\u0632\u06cc WebSocket \u0628\u0627 Hono \u0648 Bun \u062f\u0634\u0648\u0627\u0631 \u0646\u06cc\u0633\u062a \u0648 \u0627\u062d\u0633\u0627\u0633 \u06a9\u0631\u062f\u0645 \u0633\u0637\u062d \u062f\u0634\u0648\u0627\u0631\u06cc \u0622\u0646 \u0645\u0639\u0627\u062f\u0644 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc WebSocket \u0628\u0627 Socket.io \u062f\u0631 Express \u0627\u0633\u062a.  \u0645\u0646 \u0642\u0635\u062f \u062f\u0627\u0634\u062a\u0645 \u06cc\u06a9 \u067e\u0633\u062a \u062f\u0631 WebSocket \u0628\u0646\u0648\u06cc\u0633\u0645\u060c \u0627\u0645\u0627 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06cc\u06a9 API \u0627\u06cc\u0645\u0646 \u0646\u0648\u0639 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 RPC \u0628\u0627 Hono \u0646\u06cc\u0632 \u062a\u062c\u0631\u0628\u0647 \u062a\u0648\u0633\u0639\u0647 \u0628\u0633\u06cc\u0627\u0631 \u062e\u0648\u0628\u06cc \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u062f\u0627\u062f\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u067e\u0633\u062a \u0637\u0648\u0644\u0627\u0646\u06cc \u0634\u062f.  \u0645\u0646 \u0645\u0634\u062a\u0627\u0642\u0627\u0646\u0647 \u0645\u0646\u062a\u0638\u0631 \u0628\u0647 \u0631\u0648\u0632 \u0631\u0633\u0627\u0646\u06cc \u0647\u0627\u06cc \u0622\u06cc\u0646\u062f\u0647 Hono \u0647\u0633\u062a\u0645.<\/p>\n<p>\u062f\u0631 \u0645\u0648\u0631\u062f \u0622\u0646 \u0627\u0633\u062a.  \u06a9\u062f \u0646\u0648\u06cc\u0633\u06cc \u0645\u0628\u0627\u0631\u06a9!<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u0645\u0627 \u0627\u063a\u0644\u0628 \u0634\u0627\u0647\u062f \u0627\u062c\u0631\u0627\u06cc WebSocket \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0686\u0627\u0631\u0686\u0648\u0628 Express \u0648 Socket.io \u0647\u0633\u062a\u06cc\u0645. \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0628\u0647 \u0646\u0638\u0631 \u0645\u06cc\u200c\u0631\u0633\u062f \u0646\u0645\u0648\u0646\u0647\u200c\u0647\u0627\u06cc \u06a9\u0645\u062a\u0631\u06cc \u0627\u0632 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc WebSocket \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Hono \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f\u060c \u0686\u0627\u0631\u0686\u0648\u0628\u06cc \u06a9\u0647 \u0634\u0628\u06cc\u0647 Express \u0627\u0633\u062a \u0627\u0645\u0627 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631 \u0648 \u0633\u0628\u06a9\u200c\u062a\u0631 \u0627\u0633\u062a. \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u067e\u06cc\u0627\u0645 \u0631\u0633\u0627\u0646\u06cc \u0633\u0627\u062f\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Hono \u0648 &hellip;<\/p>\n","protected":false},"author":2,"featured_media":65958,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-65957","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/65957","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=65957"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/65957\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media\/65958"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=65957"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=65957"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=65957"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}