<p dir="auto">I like the design of the new <code class="notranslate">Deno.serveHttp</code> API. I think a similar design would work well for WebSockets, too.</p>
<p dir="auto">Example API:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="async function acceptWebSocket(
  conn: Deno.Conn,
  httpConn: Deno.RequestEvent
): Promise&lt;WebSocket&gt; {}"><pre class="notranslate"><span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">acceptWebSocket</span><span class="pl-kos">(</span>
  <span class="pl-s1">conn</span>: <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-smi">Conn</span><span class="pl-kos">,</span>
  <span class="pl-s1">httpConn</span>: <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-smi">RequestEvent</span>
<span class="pl-kos">)</span>: <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">WebSocket</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span></pre></div>
<p dir="auto">Example usage:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="for await (const conn of Deno.listen({ port: 80 })) {
  handleConn(conn);
}

async function handleConn(conn: Deno.Conn) {
  for await (const httpConn of Deno.serveHttp(conn)) {
    handleHttpConn(conn, httpConn);
  }
}

async function handleHttpConn(conn: Deno.Conn, httpConn: Deno.RequestEvent) {
  try {
    const ws = await Deno.acceptWebSocket(conn, httpConn);
    ws.onopen = todo;
    ws.onmessage = todo;
    ws.onerror = todo;
    ws.onclose = todo;
  } catch {
    httpConn.respondWith(new Response(&quot;Failed to accept WebSocket&quot;, { status: 400 }));
  }
}

function todo() {}"><pre class="notranslate"><span class="pl-k">for</span> <span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-s1">conn</span> <span class="pl-k">of</span> <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-en">listen</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">port</span>: <span class="pl-c1">80</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-en">handleConn</span><span class="pl-kos">(</span><span class="pl-s1">conn</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">handleConn</span><span class="pl-kos">(</span><span class="pl-s1">conn</span>: <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-smi">Conn</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">for</span> <span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-s1">httpConn</span> <span class="pl-k">of</span> <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-en">serveHttp</span><span class="pl-kos">(</span><span class="pl-s1">conn</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-en">handleHttpConn</span><span class="pl-kos">(</span><span class="pl-s1">conn</span><span class="pl-kos">,</span> <span class="pl-s1">httpConn</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">handleHttpConn</span><span class="pl-kos">(</span><span class="pl-s1">conn</span>: <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-smi">Conn</span><span class="pl-kos">,</span> <span class="pl-s1">httpConn</span>: <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-smi">RequestEvent</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">try</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">ws</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-en">acceptWebSocket</span><span class="pl-kos">(</span><span class="pl-s1">conn</span><span class="pl-kos">,</span> <span class="pl-s1">httpConn</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">onopen</span> <span class="pl-c1">=</span> <span class="pl-s1">todo</span><span class="pl-kos">;</span>
    <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">onmessage</span> <span class="pl-c1">=</span> <span class="pl-s1">todo</span><span class="pl-kos">;</span>
    <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">onerror</span> <span class="pl-c1">=</span> <span class="pl-s1">todo</span><span class="pl-kos">;</span>
    <span class="pl-s1">ws</span><span class="pl-kos">.</span><span class="pl-c1">onclose</span> <span class="pl-c1">=</span> <span class="pl-s1">todo</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span> <span class="pl-k">catch</span> <span class="pl-kos">{</span>
    <span class="pl-s1">httpConn</span><span class="pl-kos">.</span><span class="pl-en">respondWith</span><span class="pl-kos">(</span><span class="pl-k">new</span> <span class="pl-smi">Response</span><span class="pl-kos">(</span><span class="pl-s">"Failed to accept WebSocket"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">status</span>: <span class="pl-c1">400</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">function</span> <span class="pl-en">todo</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span></pre></div>
<p dir="auto">Probably looks like this:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let { respondWith, request } = await httpConn.nextRequest();
let { ws, response } = Deno.serveWebsocket(request);
respondWith(response);
// use web standard ws"><pre class="notranslate"><span class="pl-k">let</span> <span class="pl-kos">{</span> respondWith<span class="pl-kos">,</span> request <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">httpConn</span><span class="pl-kos">.</span><span class="pl-en">nextRequest</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> <span class="pl-kos">{</span> ws<span class="pl-kos">,</span> response <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-v">Deno</span><span class="pl-kos">.</span><span class="pl-en">serveWebsocket</span><span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">respondWith</span><span class="pl-kos">(</span><span class="pl-s1">response</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">// use web standard ws</span></pre></div>
<p dir="auto">Should use <a href="https://crates.io/crates/tungstenite" rel="nofollow">tungstenite</a></p>
<p dir="auto">Probably this should proceed <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="859763399" data-permission-text="Title is private" data-url="https://github.com/denoland/deno/issues/10210" data-hovercard-type="issue" data-hovercard-url="/denoland/deno/issues/10210/hovercard" href="https://github.com/denoland/deno/issues/10210">#10210</a></p>