Deno 1.9 原生网络服务器 API 和方法?

时间:2021-04-15 13:54:11

标签: http2 server-sent-events deno

我试图在 Deno 1.9 release notes 上找到更多关于原生 HTTP/2 服务器 API 的信息。我的目标是将服务器发送的事件 (SSE) 与 HTTP/2 服务器一起使用。 发行说明中提供了以下代码:

const body = new TextEncoder().encode("Hello World");
for await (const conn of Deno.listen({ port: 4500 })) {
  (async () => {
    for await (const { respondWith } of Deno.serveHttp(conn)) {
      respondWith(new Response(body));
    }
  })();
}

我希望能够处理请求、发送标头等。所以如果有人可以将我指向 API,那就太好了。

1 个答案:

答案 0 :(得分:2)

围绕 Deno.serveHttp 的 API 实际上非常基础,类似于 MDN 上记录的 ServiceWorker fetch-event API。

由于原生 HTTP 服务器仍然“不稳定”,Deno 文档仅在不稳定模式下显示它。这是一个深层链接:https://doc.deno.land/builtin/unstable#Deno.RequestEvent

总而言之,您获得了一个 Request object,并且您的任务是使用 Response object 构建/响应。 Response 构造函数上的 MDN 页面在显示响应请求时的选项方面应该非常有用。

这个例子显示了一个带有正文、状态代码和一个额外标题的响应:

    await evt.respondWith(new Response(someHtml, {
      status: 200,
      headers: new Headers({ "Content-Type": "text/html" }),
    }));

关于 SSE:目前 Deno 中没有内置服务器发送事件功能,因此就 Deno API 而言,SSE 流看起来像任何其他流响应。

生成 SSE 事件的最简单方法是使用像 Oak 这样的 HTTP 库,它对 HTTP 响应具有 native support for emitting events

如果你想更多地DIY,那么第一步是编写一个异步生成器函数,该函数生成一个 SSE 负载流,例如这个实现每秒产生 op_http_response_write 操作的累积指标:

// Function generating the SSE-formatted data stream
async function* generateEvents() {
  while (true) {
    await new Promise((r) => setTimeout(r, 1000));
    const opMetrics = Deno.metrics().ops['op_http_response_write'];
    const message = `data: ${JSON.stringify(opMetrics)}\n\n`;
    yield new TextEncoder().encode(message);
  }
}

然后,您将能够通过调用生成器函数来响应请求(在通过路径或接受标头确认它是 SSE 之后):

import { readableStreamFromIterable } from "https://deno.land/std@0.95.0/io/streams.ts";

    const stream = readableStreamFromIterable(generateEvents());
    await respondWith(new Response(stream, {
      headers: new Headers({ "Content-Type": "text/event-stream" }),
    }));

我已将一个示例程序上传到 https://crux.land/61HZ4a,它可以像这样调用:deno run --unstable --allow-net=0.0.0.0 https://crux.land/5qJEfM 并包含一个测试页面,显示接收到的 SSE 事件。