Closed5

remix や next.js の api route で websocket を proxy できるか?

ピン留めされたアイテム
naporitannaporitan

できません。諦めましょう。
DurableObjects を Hono で wrap して domain 割り当ててブラウザから new WebSocket 叩きましょう。
終わり。

naporitannaporitan

Remix

関連資料

GitHub で socket をはやしてくれと議論をしているみたい。
https://github.com/remix-run/remix/discussions/2465

これは actions で socket 経由で send したい場合なので違う。
https://zenn.dev/link/comments/0cfa1149bf96e7

実験内容

以下 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,
  });
};
naporitannaporitan

new WebSocket("ws://localhost/api/room/1?uid=111")

  • サーバーのログには何も出ない
    • remix の api route まで到達してないと予想

WebSockt の接続が保留中

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

naporitannaporitan

Next.js

関連資料

patch を当てたらできるって言ってる。さすがにやだ。
https://github.com/vercel/next.js/discussions/58698

実験内容

以下 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,
    });
  },
);
naporitannaporitan

new WebSocket("ws://localhost/api/room/1?uid=111")

  • サーバーのログには何も出ない
    • next.js の api route まで到達してないと予想

WebSocket が閉じられる

fetch("http://localhost/api/message/?uid=a&id=1")

ログが出た。url の解析、DurableObjects へのリクエストまではできている。upgrade header がないので webSocket がないので 500 が返ってくる。ただしい。

1 1

webSocket not found

500 エラー

このスクラップは3ヶ月前にクローズされました