<p dir="auto"><code class="notranslate">perf(ext/websocket): replace tokio_tungstenite server with fastwebsockets #18587</code></p>
<p dir="auto">The above commit seems to break websockets.</p>
<p dir="auto">Symptom: websocket sends do not go through until new messages arrive to the connection.</p>
<p dir="auto">It's easy to reproduce with example close to the one from <a href="https://medium.com/deno-the-complete-reference/native-web-sockets-client-server-in-deno-928678a65cf2" rel="nofollow">https://medium.com/deno-the-complete-reference/native-web-sockets-client-server-in-deno-928678a65cf2</a> replacing prompts to input text with setTimeout with sending ping-pongs.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="//chat_server.ts

import { serve } from &quot;https://deno.land/std/http/mod.ts&quot;;
function logError(msg: string) {
  console.log(msg);
  Deno.exit(1);
}
function handleConnected() {
  console.log(&quot;Connected to client ...&quot;);
}
function handleMessage(ws: WebSocket, data: string) {
  console.log(&quot;CLIENT &gt;&gt; &quot; + data);
  setTimeout(()=&gt;ws.send('pong'),2000);
  // const reply = prompt(&quot;Server &gt;&gt; &quot;) || &quot;No reply&quot;;
  // if (reply === &quot;exit&quot;) {
  //   return ws.close();
  // }
  // ws.send(reply as string);
}
function handleError(e: Event | ErrorEvent) {
  console.log(e instanceof ErrorEvent ? e.message : e.type);
}
async function reqHandler(req: Request) {
  if (req.headers.get(&quot;upgrade&quot;) != &quot;websocket&quot;) {
    return new Response(null, { status: 501 });
  }
  const { socket: ws, response } = Deno.upgradeWebSocket(req);
  ws.onopen = () =&gt; handleConnected();
  ws.onmessage = (m) =&gt; handleMessage(ws, m.data);
  ws.onclose = () =&gt; logError(&quot;Disconnected from client ...&quot;);
  ws.onerror = (e) =&gt; handleError(e);
  return response;
}
console.log(&quot;Waiting for client ...&quot;);
serve(reqHandler, { port: 8001 });"><pre class="notranslate"><code class="notranslate">//chat_server.ts

import { serve } from "https://deno.land/std/http/mod.ts";
function logError(msg: string) {
  console.log(msg);
  Deno.exit(1);
}
function handleConnected() {
  console.log("Connected to client ...");
}
function handleMessage(ws: WebSocket, data: string) {
  console.log("CLIENT &gt;&gt; " + data);
  setTimeout(()=&gt;ws.send('pong'),2000);
  // const reply = prompt("Server &gt;&gt; ") || "No reply";
  // if (reply === "exit") {
  //   return ws.close();
  // }
  // ws.send(reply as string);
}
function handleError(e: Event | ErrorEvent) {
  console.log(e instanceof ErrorEvent ? e.message : e.type);
}
async function reqHandler(req: Request) {
  if (req.headers.get("upgrade") != "websocket") {
    return new Response(null, { status: 501 });
  }
  const { socket: ws, response } = Deno.upgradeWebSocket(req);
  ws.onopen = () =&gt; handleConnected();
  ws.onmessage = (m) =&gt; handleMessage(ws, m.data);
  ws.onclose = () =&gt; logError("Disconnected from client ...");
  ws.onerror = (e) =&gt; handleError(e);
  return response;
}
console.log("Waiting for client ...");
serve(reqHandler, { port: 8001 });
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="//chat_client.ts

function logError(msg: string) {
  console.log(msg);
  Deno.exit(1);
}
function handleConnected(ws: WebSocket) {
  console.log(&quot;Connected to server ...&quot;);
  handleMessage(ws, &quot;Welcome!&quot;);
}
function handleMessage(ws: WebSocket, data: string) {
  console.log(&quot;SERVER &gt;&gt; &quot; + data);
  setTimeout(()=&gt;ws.send('ping'),2000);
  // const reply = prompt(&quot;Client &gt;&gt; &quot;) || &quot;No reply&quot;;
  // if (reply === &quot;exit&quot;) {
  //   return ws.close();
  // }
  // ws.send(reply as string);
}
function handleError(e: Event | ErrorEvent) {
  console.log(e instanceof ErrorEvent ? e.message : e.type);
}
console.log(&quot;Connecting to server ...&quot;);
try {
  const ws = new WebSocket(&quot;ws://localhost:8001&quot;);
  ws.onopen = () =&gt; handleConnected(ws);
  ws.onmessage = (m) =&gt; handleMessage(ws, m.data);
  ws.onclose = () =&gt; logError(&quot;Disconnected from server ...&quot;);
  ws.onerror = (e) =&gt; handleError(e);
} catch (err) {
  logError(&quot;Failed to connect to server ... exiting&quot;);
}"><pre class="notranslate"><code class="notranslate">//chat_client.ts

function logError(msg: string) {
  console.log(msg);
  Deno.exit(1);
}
function handleConnected(ws: WebSocket) {
  console.log("Connected to server ...");
  handleMessage(ws, "Welcome!");
}
function handleMessage(ws: WebSocket, data: string) {
  console.log("SERVER &gt;&gt; " + data);
  setTimeout(()=&gt;ws.send('ping'),2000);
  // const reply = prompt("Client &gt;&gt; ") || "No reply";
  // if (reply === "exit") {
  //   return ws.close();
  // }
  // ws.send(reply as string);
}
function handleError(e: Event | ErrorEvent) {
  console.log(e instanceof ErrorEvent ? e.message : e.type);
}
console.log("Connecting to server ...");
try {
  const ws = new WebSocket("ws://localhost:8001");
  ws.onopen = () =&gt; handleConnected(ws);
  ws.onmessage = (m) =&gt; handleMessage(ws, m.data);
  ws.onclose = () =&gt; logError("Disconnected from server ...");
  ws.onerror = (e) =&gt; handleError(e);
} catch (err) {
  logError("Failed to connect to server ... exiting");
}
</code></pre></div>
<p dir="auto">This example sends ping-pongs every 2 seconds on 1.32.3, but stalls on 1.32.4</p>
<p dir="auto">Today, I upgrade deno to 1.32.4.  Websocket break in deno 1.32.4.<br>
First message successfully send but cannot send message after timeout.<br>
It work fine in deno 1.32.3.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="	const { socket, response } = Deno.upgradeWebSocket(reqEvent.request);
	socket.onopen = () =&gt; {
		console.log(&quot;socket opened&quot;);
		socket.send(&quot;Hello World!&quot;);
	};
	socket.onmessage = (e) =&gt; {
		socket.send(&quot;message from client received&quot;);//this work
		setTimeout(() =&gt; {
			socket.send(&quot;message send after some time&quot;);//this doesn't work
			// socket.close();
		}, 2000);
	};
	socket.onclose = () =&gt; console.log(&quot;WebSocket has been closed.&quot;);
	socket.onerror = (e) =&gt; console.error(&quot;WebSocket error:&quot;, e);
	reqEvent.respondWith(response);"><pre class="notranslate">	<span class="pl-k">const</span> <span class="pl-kos">{</span> socket<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">upgradeWebSocket</span><span class="pl-kos">(</span><span class="pl-s1">reqEvent</span><span class="pl-kos">.</span><span class="pl-c1">request</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
	<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">onopen</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
		<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">"socket opened"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
		<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-s">"Hello World!"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
	<span class="pl-kos">}</span><span class="pl-kos">;</span>
	<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">onmessage</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
		<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-s">"message from client received"</span><span class="pl-kos">)</span><span class="pl-kos">;</span><span class="pl-c">//this work</span>
		<span class="pl-en">setTimeout</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
			<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-s">"message send after some time"</span><span class="pl-kos">)</span><span class="pl-kos">;</span><span class="pl-c">//this doesn't work</span>
			<span class="pl-c">// socket.close();</span>
		<span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c1">2000</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
	<span class="pl-kos">}</span><span class="pl-kos">;</span>
	<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">onclose</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">"WebSocket has been closed."</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
	<span class="pl-s1">socket</span><span class="pl-kos">.</span><span class="pl-en">onerror</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span><span class="pl-s">"WebSocket error:"</span><span class="pl-kos">,</span> <span class="pl-s1">e</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
	<span class="pl-s1">reqEvent</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></pre></div>
<p dir="auto">please fix this issue.</p>