Deno:如何在 Oak 中使用 WebSocket?

Pie*_*lle 4 websocket deno

由于 Deno 于上周三发布,我尝试使用它并重做小示例聊天应用程序,我尝试了以下操作:

import { Application, Router, send } from 'https://deno.land/x/oak/mod.ts';
import { listenAndServe } from 'https://deno.land/std/http/server.ts'

const app = new Application();
const router = new Router();

router
  .get('/ws', handleSocket);


app.use(router.routes());
app.use(router.allowedMethods());

await app.listen({ port: HTTP_PORT });
Run Code Online (Sandbox Code Playgroud)

应用程序.ts

import { WebSocket, acceptWebSocket, isWebSocketCloseEvent, acceptable } from 'https://deno.land/std/ws/mod.ts'
import { v4 } from 'https://deno.land/std/uuid/mod.ts'

const users = new Map<string, WebSocket>()

export const handleSocket = async (ctx: any) => {
  if (acceptable(ctx.request.serverRequest)) {
    const { conn, r: bufReader, w: bufWriter, headers } = ctx.request.serverRequest;
    const socket = await acceptWebSocket({
      conn,
      bufReader,
      bufWriter,
      headers,
    });

    await socketEventHandlers(socket);
  } else {
    throw new Error('Error when connecting websocket');
  }
}
...

export const socketEventHandlers = async (ws: WebSocket): Promise<void> => {
  // Register user connection
  const userId = v4.generate()

  users.set(userId, ws)
  await broadcast(`> User with the id ${userId} is connected`)

  // Wait for new messages
  for await (const event of ws) {
    const message = typeof event === 'string' ? event : ''

    await broadcast(message, userId)

    // Unregister user conection
    if (!message && isWebSocketCloseEvent(event)) {
      users.delete(userId)
      await broadcast(`> User with the id ${userId} is disconnected`)
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

套接字.ts

websocket 连接与 完美配合import { listenAndServe } from 'https://deno.land/std/http/server.ts' ,但使用上面的代码我遇到了类似 的错误WebSocket connection to 'ws://localhost:3000/ws' failed: Invalid frame header

有人有任何提示可以解决吗?谢谢 ;)

小智 5

TL;DR - 自答案被接受以来已经更新,现在更简单了。

router.get('/ws', async ctx => {
    const sock = await ctx.upgrade();
    handleSocket(sock);
});
Run Code Online (Sandbox Code Playgroud)

信用https://github.com/oakserver/oak/pull/137