Closed5
remix や next.js の api route で websocket を proxy できるか?
ピン留めされたアイテム
できません。諦めましょう。
DurableObjects を Hono で wrap して domain 割り当ててブラウザから new WebSocket
叩きましょう。
終わり。
Remix
関連資料
GitHub で socket をはやしてくれと議論をしているみたい。
これは actions で socket 経由で send したい場合なので違う。
実験内容
以下 2 つを開発者モードのコンソールで実行
new WebSocket("ws://localhost/api/room/1?uid=111")
-
fetch("http://localhost/api/message/?uid=a&id=1")
- こっちは origin まで到達して upgrade がないと言われれば OK
実験したコード
雑に DurableObjects で作った WebSocket を proxy するサーバーを書いた。
import type { LoaderFunctionArgs } from "@remix-run/cloudflare";
import { createClient } from "~/adapters/client.server";
export const loader = async ({ context, request }: LoaderFunctionArgs) => {
const client = createClient({ context, request });
const url = new URL(request.url);
const uid = url.searchParams.get("uid");
const id = url.searchParams.get("id");
console.log(uid, id);
if (!uid || !id) return new Response("Invalid request", { status: 400 });
const res = await client.room[":id"].$get({
query: { uid },
param: { id },
});
console.log(res.url);
if (!("webSocket" in res) || !(res.webSocket instanceof WebSocket)) {
console.log("webSocket not found");
return new Response("Invalid response", { status: 500 });
}
return new Response(null, {
status: res.status,
headers: res.headers,
webSocket: res.webSocket,
});
};
new WebSocket("ws://localhost/api/room/1?uid=111")
- サーバーのログには何も出ない
- remix の api route まで到達してないと予想
fetch("http://localhost/api/message/?uid=a&id=1")
ログが出た。url の解析、DurableObjects へのリクエストまではできている。upgrade header がないので webSocket
がないので 500 が返ってくる。ただしい。
a 1
http://localhost:8787/room/1?uid=a
webSocket not found
Next.js
関連資料
patch を当てたらできるって言ってる。さすがにやだ。
実験内容
以下 2 つを開発者モードのコンソールで実行
new WebSocket("ws://localhost/api/room/1?uid=111")
-
fetch("http://localhost/api/message/?uid=a&id=1")
- こっちは origin まで到達して upgrade がないと言われれば OK
実験したコード
雑に DurableObjects で作った WebSocket を proxy するサーバーを書いた。
import { api } from "@adapters/api/client";
import { getRequestContext } from "@cloudflare/next-on-pages";
import { Hono } from "hono";
import { logger } from "hono/logger";
import { upgrade } from "./upgrade";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
export const runtime = "edge";
const app = new Hono().basePath("/api");
const route = app.get(
"/room/:id",
upgrade(),
zValidator("query", z.object({ uid: z.string() })),
async (c) => {
const roomId = c.req.param("id");
const query = c.req.valid("query");
console.log(query.uid, roomId);
const res = await api(c.req.url).room[":id"].$get(
{
param: { id: roomId },
query: { uid: query.uid },
},
{ init: c.req.raw },
);
console.log(res.url);
if (!("webSocket" in res) || !(res.webSocket instanceof WebSocket)) {
console.log("webSocket not found");
return new Response("Invalid response", { status: 500 });
}
return new Response(null, {
status: res.status,
headers: res.headers,
webSocket: res.webSocket,
});
},
);
new WebSocket("ws://localhost/api/room/1?uid=111")
- サーバーのログには何も出ない
- next.js の api route まで到達してないと予想
fetch("http://localhost/api/message/?uid=a&id=1")
ログが出た。url の解析、DurableObjects へのリクエストまではできている。upgrade header がないので webSocket
がないので 500 が返ってくる。ただしい。
1 1
webSocket not found
このスクラップは5ヶ月前にクローズされました