PageSourceSearch

https://socket.io/assets/js/ef1ddbdf.dfb06e8a.js

js socket.io collected 2026-09-24 07:26:26 UTC 22,248 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[6957],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},s=Object.keys(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),h=p(n),m=o,u=h["".concat(l,".").concat(m)]||h[m]||d[m]||s;return n?r.createElement(u,a(a({ref:t},c),{},{components:n})):r.createElement(u,a({ref:t},c))}));function u(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,a=new Array(s);a[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[h]="string"==typeof e?e:o,a[1]=i;for(var p=2;p<s;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},1238:(e,t,n)=>{n.r(t),n.d(t,{contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=n(3117),o=(n(7294),n(3905));const s={title:"Socket.IO with WebTransport"},a="Socket.IO with WebTransport",i={type:"mdx",permalink:"/get-started/webtransport",source:"@site/src/pages/get-started/webtransport.md",title:"Socket.IO with WebTransport",description:"Support for WebTransport has been added in version 4.7.0 (June 2023).",frontMatter:{title:"Socket.IO with WebTransport"}},l=[{value:"Requirements",id:"requirements",level:2},{value:"SSL certificate",id:"ssl-certificate",level:2},{value:"Basic HTTPS server",id:"basic-https-server",level:2},{value:"Socket.IO server",id:"socketio-server",level:2},{value:"WebTransport",id:"webtransport",level:2},{value:"Conclusion",id:"conclusion",level:2}],p={toc:l},c="wrapper";function h(e){let{components:t,...s}=e;return(0,o.kt)(c,(0,r.Z)({},p,s,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"socketio-with-webtransport"},"Socket.IO with WebTransport"),(0,o.kt)("p",null,"Support for WebTransport has been added in version ",(0,o.kt)("a",{parentName:"p",href:"/docs/v4/changelog/4.7.0"},"4.7.0")," (June 2023)."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"In short, WebTransport is an alternative to WebSocket which fixes several performance issues that plague WebSockets like ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Head-of-line_blocking"},"head-of-line blocking"),"."),(0,o.kt)("p",{parentName:"admonition"},"If you want more information about this new web API, please check:"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://w3c.github.io/webtransport/"},"https://w3c.github.io/webtransport/")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/API/WebTransport"},"https://developer.mozilla.org/en-US/docs/Web/API/WebTransport")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://developer.chrome.com/articles/webtransport/"},"https://developer.chrome.com/articles/webtransport/")))),(0,o.kt)("p",null,"In this guide, we will create a S
1ocket.IO server that accepts WebTransport connections."),(0,o.kt)("p",null,"Here we go!"),(0,o.kt)("h2",{id:"requirements"},"Requirements"),(0,o.kt)("p",null,"Please use at least Node.js 18 (the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/nodejs/Release#release-schedule"},"current LTS version")," at the time of writing)."),(0,o.kt)("h2",{id:"ssl-certificate"},"SSL certificate"),(0,o.kt)("p",null,"First, let's create a new directory for our project:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"mkdir webtransport-sample-project && cd webtransport-sample-project\n")),(0,o.kt)("p",null,"WebTransport only works in secure contexts (HTTPS), so we will need an SSL certificate."),(0,o.kt)("p",null,"You can run the following command to issue a new certificate:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},"openssl req -new -x509 -nodes \\\n    -out cert.pem \\\n    -keyout key.pem \\\n    -newkey ec \\\n    -pkeyopt ec_paramgen_curve:prime256v1 \\\n    -subj '/CN=127.0.0.1' \\\n    -days 14\n")),(0,o.kt)("p",null,"Reference: ",(0,o.kt)("a",{parentName:"p",href:"https://www.openssl.org/docs/man3.1/man1/openssl-req.html"},"https://www.openssl.org/docs/man3.1/man1/openssl-req.html")),(0,o.kt)("p",null,"This will generate a private key and a certificate which comply with the requirements listed ",(0,o.kt)("a",{parentName:"p",href:"https://w3c.github.io/webtransport/#web-transport-configuration"},"here"),": "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"the total length of the validity period MUST NOT exceed two weeks"),(0,o.kt)("li",{parentName:"ul"},"the exact list of allowed public key algorithms ","[...]"," MUST include ECDSA with the secp256r1 (NIST P-256) named group")),(0,o.kt)("p",null,"OK, so you should now have:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},".\n\u251c\u2500\u2500 cert.pem\n\u2514\u2500\u2500 key.pem\n")),(0,o.kt)("h2",{id:"basic-https-server"},"Basic HTTPS server"),(0,o.kt)("p",null,"Then, let's create a basic Node.js HTTPS server:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="package.json"',title:'"package.json"'},'{\n  "name": "webtransport-sample-project",\n  "version": "0.0.1",\n  "description": "Socket.IO with WebTransport",\n  "private": true,\n  "type": "module"\n}\n')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="index.js"',title:'"index.js"'},'import { readFile } from "node:fs/promises";\nimport { createServer } from "node:https";\n\nconst key = await readFile("./key.pem");\nconst cert = await readFile("./cert.pem");\n\nconst httpsServer = createServer({\n  key,\n  cert\n}, async (req, res) => {\n  if (req.method === "GET" && req.url === "/") {\n    const content = await readFile("./index.html");\n    res.writeHead(200, {\n      "content-type": "text/html"\n    });\n    res.write(content);\n    res.end();\n  } else {\n    res.writeHead(404).end();\n  }\n});\n\nconst port = process.env.PORT || 3000;\n\nhttpsServer.listen(port, () => {\n  console.log(`server listening at https://localhost:${port}`);\n});\n')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="index.html"',title:'"index.html"'},'<!doctype html>\n<html lang="en">\n  <head>\n    <meta charset="UTF-8">\n    <title>Socket.IO WebTransport example</title>\n  </head>\n  <body>\n    Hello world!\n  </body>\n</html>\n')),(0,o.kt)("p",null,"Nothing fancy here, we just serve the content of the ",(0,o.kt)("inlineCode",{parentName:"p"},"index.html")," file at ",(0,o.kt)("inlineCode",{parentName:"p"},"/"),", and return an HTTP 404 error code otherwise."),(0,o.kt)("p",null,"Reference: ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org/api/https.html"},"https://nodejs.org/api/https.html")),(0,o.kt)("p",null,"You can start the server by running ",(0,o.kt)("inlineCode",{parentName:"p"},"node index.js"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"$ node index.js\nserver listening at https://localhost:3000\n")),(0,o.kt)("p",null,"Now, let's open a new browser window:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell",metastring:'title="open_browser.sh"',title:'"open_browser.sh"'},"#!/bin/bash\nHASH=`openssl x509 -pubkey -noout -in cert.pem |\n    openssl pkey -pubin -outform der |\n    openssl dgst -sha256 -binary |\n    base64`\n\nchromium \\\n    --ignore-certificate-errors-spki-list=$HASH \\\n    https://localhost:3000\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"--ignore-certificate-errors-spki-list")," flag tells Chromium to accept our self-signed certificate without complaining:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Hello world displayed in the browser",src:n(1982).Z,width:"929",height:"807"})),(0,o.kt)("p",null,"Our SSL certificate is indeed deemed valid:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Browser indicating that our certificate is valid",src:n(366).Z,width:"929",height:"807"})),(0,o.kt)("p",null,"Great! You should now have:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},".\n\u251c\u2500\u2500 cert.pem\n\u251c\u2500\u2500 index.html\n\u251c\u2500\u2500 index.js\n\u251c\u2500\u2500 key.pem\n\u251c\u2500\u2500 open_browser.sh\n\u2514\u2500\u2500 package.json\n")),(0,o.kt)("h2",{id:"socketio-server"},"Socket.IO server"),(0,o.kt)("p",null,"Now, let's install the ",(0,o.kt)("inlineCode",{parentName:"p"},"socket.io")," package:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"}
1,"npm i socket.io\n")),(0,o.kt)("p",null,"We now create a Socket.IO server and attach it to our existing HTTPS server:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="index.js"',title:'"index.js"'},'import { readFile } from "node:fs/promises";\nimport { createServer } from "node:https";\n// highlight-next-line\nimport { Server } from "socket.io";\n\nconst key = await readFile("./key.pem");\nconst cert = await readFile("./cert.pem");\n\nconst httpsServer = createServer({\n  key,\n  cert\n}, async (req, res) => {\n  if (req.method === "GET" && req.url === "/") {\n    const content = await readFile("./index.html");\n    res.writeHead(200, {\n      "content-type": "text/html"\n    });\n    res.write(content);\n    res.end();\n  } else {\n    res.writeHead(404).end();\n  }\n});\n\nconst port = process.env.PORT || 3000;\n\nhttpsServer.listen(port, () => {\n  console.log(`server listening at https://localhost:${port}`);\n});\n\n// highlight-start\nconst io = new Server(httpsServer);\n\nio.on("connection", (socket) => {\n  console.log(`connected with transport ${socket.conn.transport.name}`);\n\n  socket.conn.on("upgrade", (transport) => {\n    console.log(`transport upgraded to ${transport.name}`);\n  });\n\n  socket.on("disconnect", (reason) => {\n    console.log(`disconnected due to ${reason}`);\n  });\n});\n// highlight-end\n')),(0,o.kt)("p",null,"Let's update the client accordingly:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="index.html"',title:'"index.html"'},'<!doctype html>\n<html lang="en">\n  <head>\n    <meta charset="UTF-8">\n    <title>Socket.IO WebTransport example</title>\n  </head>\n  <body>\n    // highlight-start\n    <p>Status: <span id="status">Disconnected</span></p>\n    <p>Transport: <span id="transport">N/A</span></p>\n\n    <script src="/socket.io/socket.io.js"><\/script>\n    <script>\n      const $status = document.getElementById("status");\n      const $transport = document.getElementById("transport");\n\n      const socket = io();\n\n      socket.on("connect", () => {\n        console.log(`connected with transport ${socket.io.engine.transport.name}`);\n\n        $status.innerText = "Connected";\n        $transport.innerText = socket.io.engine.transport.name;\n\n        socket.io.engine.on("upgrade", (transport) => {\n          console.log(`transport upgraded to ${transport.name}`);\n\n          $transport.innerText = transport.name;\n        });\n      });\n\n      socket.on("connect_error", (err) => {\n        console.log(`connect_error due to ${err.message}`);\n      });\n\n      socket.on("disconnect", (reason) => {\n        console.log(`disconnect due to ${reason}`);\n\n        $status.innerText = "Disconnected";\n        $transport.innerText = "N/A";\n      });\n    <\/script>\n    // highlight-end\n  </body>\n</html>\n')),(0,o.kt)("p",null,"A few explanations:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"client bundle")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'<script src="/socket.io/socket.io.js"><\/script>\n')),(0,o.kt)("p",null,"The Socket.IO client bundle is served by the server at ",(0,o.kt)("inlineCode",{parentName:"p"},"/socket.io/socket.io.js"),"."),(0,o.kt)("p",null,"We could also have used the minified bundle (",(0,o.kt)("inlineCode",{parentName:"p"},"/socket.io/socket.io.min.js"),", without debug logs) or a CDN (for example ",(0,o.kt)("a",{parentName:"p",href:"https://cdn.socket.io/4.7.2/socket.io.min.js"},"https://cdn.socket.io/4.7.2/socket.io.min.js"),")."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"transport")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("connect", () => {\n  console.log(`connected with transport ${socket.io.engine.transport.name}`);\n  // ...\n});\n')),(0,o.kt)("p",null,"In the Socket.IO jargon, a Transport is a way to establish a connection between a client and a server. Since version 4.7.0, there are now 3 available transports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"HTTP long-polling"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API"},"WebSocket")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/API/WebTransport"},"WebTransport"))),(0,o.kt)("p",null,"By default, the Socket.IO client will always try HTTP long-polling first, since it is the transport which is the most likely to successfully establish a connection. It will then quietly upgrade to more performant transports, like WebSocket or WebTransport."),(0,o.kt)("p",null,"More about this upgrade mechanism ",(0,o.kt)("a",{parentName:"p",href:"/docs/v4/how-it-works/"},"here"),"."),(0,o.kt)("p",null,"OK, so let's restart our server. You should now see:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Browser indicating that the connection is established with WebSocket",src:n(109).Z,width:"929",height:"807"})),(0,o.kt)("p",null,"So far, so good."),(0,o.kt)("h2",{id:"webtransport"},"WebTransport"),(0,o.kt)("p",null,"On the client side, WebTransport is currently available in all major browsers but Safari: ",(0,o.kt)("a",{parentName:"p",href:"https://caniuse.com/webtransport"},"https://caniuse.com/webtransport")),(0,o.kt)("p",null,"On the server side, until support for WebTransport lands ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/nodejs/node/issues/38478"},"in Node.js")," (and ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/denoland/deno/issues/1558"},"in Deno"),"), we can use the ",(0,o.kt)("inlineCode",{parentName:"p"},"@fails-components/webtransport")," package maintained by ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/martenrichter"},"Marten Richter"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"npm i @fails-components/webtransport @fails-components/webtransport-transport-http3-quiche\n")),(0,o.kt)("p",null,"Source: ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/fails-components/webtransport"},"https://github.com/fails-components/webtransport")),(0,o.kt)("p",null,"Let's create an HTTP/3 server and forward the WebTransport sessions to the Socket.IO server: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="index.js"',title:'"index.js"'},'import { readFile } from "node:fs/promises";\nimport { createServer } from "node:https";\nimport { Server } from "socket.io";
1\n// highlight-next-line\nimport { Http3Server } from "@fails-components/webtransport";\n\nconst key = await readFile("./key.pem");\nconst cert = await readFile("./cert.pem");\n\nconst httpsServer = createServer({\n  key,\n  cert\n}, async (req, res) => {\n  if (req.method === "GET" && req.url === "/") {\n    const content = await readFile("./index.html");\n    res.writeHead(200, {\n      "content-type": "text/html"\n    });\n    res.write(content);\n    res.end();\n  } else {\n    res.writeHead(404).end();\n  }\n});\n\nconst port = process.env.PORT || 3000;\n\nhttpsServer.listen(port, () => {\n  console.log(`server listening at https://localhost:${port}`);\n});\n\n// highlight-start\nconst io = new Server(httpsServer, {\n  transports: ["polling", "websocket", "webtransport"]\n});\n// highlight-end\n\nio.on("connection", (socket) => {\n  console.log(`connected with transport ${socket.conn.transport.name}`);\n\n  socket.conn.on("upgrade", (transport) => {\n    console.log(`transport upgraded to ${transport.name}`);\n  });\n\n  socket.on("disconnect", (reason) => {\n    console.log(`disconnected due to ${reason}`);\n  });\n});\n\n// highlight-start\nconst h3Server = new Http3Server({\n  port,\n  host: "0.0.0.0",\n  secret: "changeit",\n  cert,\n  privKey: key,\n});\n\nh3Server.startServer();\n\n(async () => {\n  const stream = await h3Server.sessionStream("/socket.io/");\n  const sessionReader = stream.getReader();\n\n  while (true) {\n    const { done, value } = await sessionReader.read();\n    if (done) {\n      break;\n    }\n    io.engine.onWebTransportSession(value);\n  }\n})();\n// highlight-end\n')),(0,o.kt)("p",null,"This should have been sufficient, but there is an error in the browser nonetheless:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Browser indicating an error with WebTransport",src:n(5294).Z,width:"929",height:"807"})),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If someone has any clue about this, please ping us.")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Even if WebTransport fails (which might also happen if something between the client and the server blocks the connection), the connection is successfully established with WebSocket. ")),(0,o.kt)("p",null,"A quick workaround is to use ",(0,o.kt)("inlineCode",{parentName:"p"},"127.0.0.1")," instead of ",(0,o.kt)("inlineCode",{parentName:"p"},"localhost"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="index.html"',title:'"index.html"'},'<!doctype html>\n<html lang="en">\n  <head>\n    <meta charset="UTF-8">\n    <title>Socket.IO WebTransport example</title>\n  </head>\n  <body>\n    <p>Status: <span id="status">Disconnected</span></p>\n    <p>Transport: <span id="transport">N/A</span></p>\n\n    <script src="/socket.io/socket.io.js"><\/script>\n    <script>\n      const $status = document.getElementById("status");\n      const $transport = document.getElementById("transport");\n\n      // highlight-start\n      const socket = io({\n        transportOptions: {\n          webtransport: {\n            hostname: "127.0.0.1"\n          }\n        }\n      });\n      // highlight-end\n\n      socket.on("connect", () => {\n        console.log(`connected with transport ${socket.io.engine.transport.name}`);\n\n        $status.innerText = "Connected";\n        $transport.innerText = socket.io.engine.transport.name;\n\n        socket.io.engine.on("upgrade", (transport) => {\n          console.log(`transport upgraded to ${transport.name}`);\n\n          $transport.innerText = transport.name;\n        });\n      });\n\n      socket.on("connect_error", (err) => {\n        console.log(`connect_error due to ${err.message}`);\n      });\n\n      socket.on("disconnect", (reason) => {\n        console.log(`disconnect due to ${reason}`);\n\n        $status.innerText = "Disconnected";\n        $transport.innerText = "N/A";\n      });\n    <\/script>\n  </body>\n</html>\n')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell",metastring:'title="open_browser.sh"',title:'"open_browser.sh"'},"#!/bin/bash\nHASH=`openssl x509 -pubkey -noout -in cert.pem |\n    openssl pkey -pubin -outform der |\n    openssl dgst -sha256 -binary |\n    base64`\n\nchromium \\\n    --ignore-certificate-errors-spki-list=$HASH \\\n# highlight-next-line\n    --origin-to-force-quic-on=127.0.0.1:3000 \\\n    https://localhost:3000\n")),(0,o.kt)("p",null,"And ",(0,o.kt)("em",{parentName:"p"},"voil\xe0!")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Browser indicating that the connection is established with WebTransport",src:n(4098).Z,width:"929",height:"807"})),(0,o.kt)("h2",{id:"conclusion"},"Conclusion"),(0,o.kt)("p",null,"Like WebSocket more than 10 years ago (!), Socket.IO now allows you to benefit from the performance improvements brought by WebTransport, ",(0,o.kt)("strong",{parentName:"p"},"without worrying about browser compatibility"),"."),(0,o.kt)("p",null,"Thanks for reading!"))}h.isMDXComponent=!0},1982:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/webtransport-example-1-1253583a3fa0ef08e8371768fb3169ec.png"},366:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/webtransport-example-2-8d6a861afa64e2f5a0198158585575dc.png"},109:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/webtransport-example-3-12560570feb6e228099db87f0528b118.png"},5294:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/webtransport-example-4-49cc8fe002d4063f8a6e3e0f0370d735.png"}
1,4098:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/webtransport-example-5-b7031531aec8681f595a2f69ce5d56dc.png"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.