PageSourceSearch

https://socket.io/assets/js/13b2e25f.c198b8c7.js

js socket.io collected 2026-09-24 07:26:36 UTC 151,875 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[7179],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(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,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m="mdxType",k={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=p(n),d=r,u=m["".concat(s,".").concat(d)]||m[d]||k[d]||o;return n?a.createElement(u,l(l({ref:t},c),{},{components:n})):a.createElement(u,l({ref:t},c))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[m]="string"==typeof e?e:r,l[1]=i;for(var p=2;p<o;p++)l[p]=n[p];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}d.displayName="MDXCreateElement"},5887:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>m});var a=n(3117),r=(n(7294),n(3905)),o=n(941),l=n(4996);const i={title:"Server API",sidebar_label:"API",sidebar_position:1,slug:"/server-api/",toc_max_heading_level:4},s=void 0,p={unversionedId:"server-api",id:"server-api",title:"Server API",description:"Server",source:"@site/docs/server-api.md",sourceDirName:".",slug:"/server-api/",permalink:"/docs/v4/server-api/",draft:!1,editUrl:"https://github.com/socketio/socket.io-website/edit/main/docs/server-api.md",tags:[],version:"current",lastUpdatedAt:1784117104,formattedLastUpdatedAt:"Jul 15, 2026",sidebarPosition:1,frontMatter:{title:"Server API",sidebar_label:"API",sidebar_position:1,slug:"/server-api/",toc_max_heading_level:4},sidebar:"serverSidebar",next:{title:"Options",permalink:"/docs/v4/server-options/"}},c={},m=[{value:"Server",id:"server",level:2},{value:"Constructor",id:"constructor",level:3},{value:"new Server(httpServer, options)",id:"new-serverhttpserver-options",level:4},{value:"new Server(port, options)",id:"new-serverport-options",level:4},{value:"new Server(options)",id:"new-serveroptions",level:4},{value:"Events",id:"events",level:3},{value:"Event: &#39;connect&#39;",id:"event-connect",level:4},{value:"Event: &#39;connection&#39;",id:"event-connection",level:4},{value:"Event: &#39;new_namespace&#39;",id:"event-new_namespace",level:4},{value:"Attributes",id:"attributes",level:3},{value:"server.engine",id:"serverengine",level:4},{value:"server.sockets",id:"serversockets",level:4},{value:"Methods",id:"methods",level:3},{value:"server.adapter(value)",id:"serveradaptervalue",level:4},{value:"server.attach(httpServer, options)",id:"serverattachhttpserver-options",level:4},{value:"server.attach(port, options)",id:"serverattachport-options",level:4},{value:"server.attachApp(app, options)",id:"serverattachappapp-options",level:4},{value:"server.bind(engine)",id:"serverbindengine",level:4},{value:"server.close(callback)",id:"serverclosecallback",level:4},{value:"server.disconnectSockets(close)",id:"serverdisconnectsocketsclose",level:4},{value:"server.emit(eventName, ...args)",id:"serveremiteventname-args",level:4},{value:"server.emitWithAck(eventName, ...args)",id:"serveremitwithackeventname-args",level:4},{value:"server.except(rooms)",id:"serverexceptrooms",level:4},{value:"server.fetchSockets()",id:"serverfetchsockets",level:4},{value:"server.in(room)",id:"serverinroom",level:4},{value:"server.listen(httpServer, options)",id:"serverlistenhttpserver-options",level:4},{value:"server.listen(port, options)",id:"serverlistenport-options",level:4},{value:"server.of(nsp)",id:"serverofnsp",level:4},{value:"server.on(eventName, listener)",id:"serveroneventname-listener",level:4},{value:"server.onconnection(socket)",id:"serveronconnectionsocket",level:4},{value:"server.path(value)",id:"serverpathvalue",level:4},{value:"server.serveClient(value)",id:"serverserveclientvalue",level:4},{value:"server.serverSideEmit(eventName, ...args)",id:"serverserversideemiteventname-args",level:4},{value:"server.serverSideEmitWithAck(eventName, ...args)",id:"serverserversideemitwithackeventname-args",level:4},{value:"server.socketsJoin(rooms)",id:"serversocketsjoinrooms",level:4},{value:"server.socketsLeave(rooms)",id:"serversocketsleaverooms",level:4},{value:"server.timeout(value)",id:"servertimeoutvalue",level:4},{value:"server.to(room)",id:"servertoroom",level:4},{value:"server.use(fn)",id:"serverusefn",level:4},{value:"Namespace",id:"namespace",level:2},{value:"Attributes",id:"attributes-1",level:3},{value:"namespace.adapter",id:"namespaceadapter",level:4},{value:"namespace.name",id:"namespacename",level:4}
1,{value:"namespace.sockets",id:"namespacesockets",level:4},{value:"Events",id:"events-1",level:3},{value:"Event: &#39;connect&#39;",id:"event-connect-1",level:4},{value:"Event: &#39;connection&#39;",id:"event-connection-1",level:4},{value:"Methods",id:"methods-1",level:3},{value:"namespace.allSockets()",id:"namespaceallsockets",level:4},{value:"namespace.disconnectSockets(close)",id:"namespacedisconnectsocketsclose",level:4},{value:"namespace.emit(eventName, ...args)",id:"namespaceemiteventname-args",level:4},{value:"namespace.emitWithAck(eventName, ...args)",id:"namespaceemitwithackeventname-args",level:4},{value:"namespace.except(rooms)",id:"namespaceexceptrooms",level:4},{value:"namespace.fetchSockets()",id:"namespacefetchsockets",level:4},{value:"namespace.in(room)",id:"namespaceinroom",level:4},{value:"namespace.serverSideEmit(eventName, ...args)",id:"namespaceserversideemiteventname-args",level:4},{value:"namespace.serverSideEmitWithAck(eventName, ...args)",id:"namespaceserversideemitwithackeventname-args",level:4},{value:"namespace.socketsJoin(rooms)",id:"namespacesocketsjoinrooms",level:4},{value:"namespace.socketsLeave(rooms)",id:"namespacesocketsleaverooms",level:4},{value:"namespace.timeout(value)",id:"namespacetimeoutvalue",level:4},{value:"namespace.to(room)",id:"namespacetoroom",level:4},{value:"namespace.use(fn)",id:"namespaceusefn",level:4},{value:"Flags",id:"flags",level:3},{value:"Flag: &#39;local&#39;",id:"flag-local",level:4},{value:"Flag: &#39;volatile&#39;",id:"flag-volatile",level:4},{value:"Socket",id:"socket",level:2},{value:"Events",id:"events-2",level:3},{value:"Event: &#39;disconnect&#39;",id:"event-disconnect",level:4},{value:"Event: &#39;disconnecting&#39;",id:"event-disconnecting",level:4},{value:"Attributes",id:"attributes-2",level:3},{value:"socket.client",id:"socketclient",level:4},{value:"socket.conn",id:"socketconn",level:4},{value:"socket.data",id:"socketdata",level:4},{value:"socket.handshake",id:"sockethandshake",level:4},{value:"socket.id",id:"socketid",level:4},{value:"socket.recovered",id:"socketrecovered",level:4},{value:"socket.request",id:"socketrequest",level:4},{value:"socket.rooms",id:"socketrooms",level:4},{value:"Methods",id:"methods-2",level:3},{value:"socket.compress(value)",id:"socketcompressvalue",level:4},{value:"socket.disconnect(close)",id:"socketdisconnectclose",level:4},{value:"socket.emit(eventName, ...args)",id:"socketemiteventname-args",level:4},{value:"socket.emitWithAck(eventName, ...args)",id:"socketemitwithackeventname-args",level:4},{value:"socket.eventNames()",id:"socketeventnames",level:4},{value:"socket.except(rooms)",id:"socketexceptrooms",level:4},{value:"socket.in(room)",id:"socketinroom",level:4},{value:"socket.join(room)",id:"socketjoinroom",level:4},{value:"socket.leave(room)",id:"socketleaveroom",level:4},{value:"socket.listenersAny()",id:"socketlistenersany",level:4},{value:"socket.listenersAnyOutgoing()",id:"socketlistenersanyoutgoing",level:4},{value:"socket.offAny(listener)",id:"socketoffanylistener",level:4},{value:"socket.offAnyOutgoing(listener)",id:"socketoffanyoutgoinglistener",level:4},{value:"socket.on(eventName, callback)",id:"socketoneventname-callback",level:4},{value:"socket.onAny(callback)",id:"socketonanycallback",level:4},{value:"socket.onAnyOutgoing(callback)",id:"socketonanyoutgoingcallback",level:4},{value:"socket.once(eventName, listener)",id:"socketonceeventname-listener",level:4},{value:"socket.prependAny(callback)",id:"socketprependanycallback",level:4},{value:"socket.prependAnyOutgoing(callback)",id:"socketprependanyoutgoingcallback",level:4},{value:"socket.removeAllListeners(eventName)",id:"socketremovealllistenerseventname",level:4},{value:"socket.removeListener(eventName, listener)",id:"socketremovelistenereventname-listener",level:4},{value:"socket.send(...args)",id:"socketsendargs",level:4},{value:"socket.timeout(value)",id:"sockettimeoutvalue",level:4},{value:"socket.to(room)",id:"sockettoroom",level:4},{value:"socket.use(fn)",id:"socketusefn",level:4},{value:"Flags",id:"flags-1",level:3},{value:"Flag: &#39;broadcast&#39;",id:"flag-broadcast",level:4},{value:"Flag: &#39;volatile&#39;",id:"flag-volatile-1",level:4},{value:"Client",id:"client",level:2},{value:"Attributes",id:"attributes-3",level:3},{value:"client.conn",id:"clientconn",level:4},{value:"client.request",id:"clientrequest",level:4},{value:"Engine",id:"engine",level:2},{value:"Events",id:"events-3",level:3},{value:"Event: &#39;connection_error&#39;",id:"event-connection_error",level:4},{value:"Event: &#39;headers&#39;",id:"event-headers",level:4},{value:"Event: &#39;initial_headers&#39;",id:"event-initial_headers",level:4},{value:"Attributes",id:"attributes-4",level:3},{value:"engine.clientsCount",id:"engineclientscount",level:4},{value:"Methods",id:"methods-3",level:3},{value:"engine.generateId",id:"enginegenerateid",level:4},{value:"engine.handleUpgrade(request, socket, head)",id:"enginehandleupgraderequest-socket-head",level:4},{value:"engine.use(middleware)",id:"engineusemiddleware",level:4}],k={toc:m},d="wrapper";
1function u(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,a.Z)({},k,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"server"},"Server"),(0,r.kt)(o.Z,{alt:"Server in the class diagram for the server",sources:{light:(0,l.Z)("/images/server-class-diagram-server.png"),dark:(0,l.Z)("/images/server-class-diagram-server-dark.png")},mdxType:"ThemedImage"}),(0,r.kt)("p",null,"Related documentation pages:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v4/server-installation/"},"installation")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v4/server-initialization/"},"initialization")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v4/server-instance/"},"details of the server instance"))),(0,r.kt)("h3",{id:"constructor"},"Constructor"),(0,r.kt)("h4",{id:"new-serverhttpserver-options"},"new Server(httpServer","[, options]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"httpServer")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/api/http.html#class-httpserver"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.Server>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/api/https.html#class-httpsserver"},(0,r.kt)("inlineCode",{parentName:"a"},"<https.Server>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"options")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { createServer } from "http";\nimport { Server } from "socket.io";\n\nconst httpServer = createServer();\nconst io = new Server(httpServer, {\n  // options\n});\n\nio.on("connection", (socket) => {\n  // ...\n});\n\nhttpServer.listen(3000);\n')),(0,r.kt)("p",null,"The complete list of available options can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-options/"},"here"),"."),(0,r.kt)("h4",{id:"new-serverport-options"},"new Server(port","[, options]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"port")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"options")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io";\n\nconst io = new Server(3000, {\n  // options\n});\n\nio.on("connection", (socket) => {\n  // ...\n});\n')),(0,r.kt)("p",null,"The complete list of available options can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-options/"},"here"),"."),(0,r.kt)("h4",{id:"new-serveroptions"},"new Server(options)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"options")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io";\n\nconst io = new Server({\n  // options\n});\n\nio.on("connection", (socket) => {\n  // ...\n});\n\nio.listen(3000);\n')),(0,r.kt)("p",null,"The complete list of available options can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-options/"},"here"),"."),(0,r.kt)("h3",{id:"events"},"Events"),(0,r.kt)("h4",{id:"event-connect"},"Event: 'connect'"),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#event-connection"},'Event: "connection"'),"."),(0,r.kt)("h4",{id:"event-connection"},"Event: 'connection'"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"socket")," ",(0,r.kt)("em",{parentName:"li"},"(Socket)")," socket connection with client")),(0,r.kt)("p",null,"Fired upon a connection from client."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  // ...\n});\n')),(0,r.kt)("h4",{id:"event-new_namespace"},"Event: 'new_namespace'"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"namespace")," ",(0,r.kt)("a",{parentName:"li",href:"#namespace"},(0,r.kt)("inlineCode",{parentName:"a"},"Namespace")))),(0,r.kt)("p",null,"Fired when a new namespace is created:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"}
1,'io.on("new_namespace", (namespace) => {\n  // ...\n});\n')),(0,r.kt)("p",null,"This can be useful for example:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"to attach a shared middleware to each namespace")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("new_namespace", (namespace) => {\n  namespace.use(myMiddleware);\n});\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"to track the ",(0,r.kt)("a",{parentName:"li",href:"/docs/v4/namespaces/#dynamic-namespaces"},"dynamically created")," namespaces")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of(/\\/nsp-\\w+/);\n\nio.on("new_namespace", (namespace) => {\n  console.log(namespace.name);\n});\n')),(0,r.kt)("h3",{id:"attributes"},"Attributes"),(0,r.kt)("h4",{id:"serverengine"},"server.engine"),(0,r.kt)("p",null,"A reference to the underlying Engine.IO server. See ",(0,r.kt)("a",{parentName:"p",href:"#engine"},"here"),"."),(0,r.kt)("h4",{id:"serversockets"},"server.sockets"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#namespace"},(0,r.kt)("inlineCode",{parentName:"a"},"<Namespace>")))),(0,r.kt)("p",null,"An alias for the main namespace (",(0,r.kt)("inlineCode",{parentName:"p"},"/"),")."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.sockets.emit("hi", "everyone");\n// is equivalent to\nio.of("/").emit("hi", "everyone");\n')),(0,r.kt)("h3",{id:"methods"},"Methods"),(0,r.kt)("h4",{id:"serveradaptervalue"},"server.adapter(","[value]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"/docs/v4/adapter/"},(0,r.kt)("inlineCode",{parentName:"a"},"<Adapter>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"<Server>"))," | ",(0,r.kt)("a",{parentName:"li",href:"/docs/v4/adapter/"},(0,r.kt)("inlineCode",{parentName:"a"},"<Adapter>")))),(0,r.kt)("p",null,"Sets the adapter ",(0,r.kt)("inlineCode",{parentName:"p"},"value"),". Defaults to an instance of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Adapter")," that ships with socket.io which is memory based. See ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/socketio/socket.io-adapter"},"socket.io-adapter"),". If no arguments are supplied this method returns the current value."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io"; \nimport { createAdapter } from "@socket.io/redis-adapter";\nimport { createClient } from "redis";\n\nconst io = new Server();\n\nconst pubClient = createClient({ host: "localhost", port: 6379 });\nconst subClient = pubClient.duplicate();\n\nio.adapter(createAdapter(pubClient, subClient));\n\n// redis@3\nio.listen(3000);\n\n// redis@4\nPromise.all([pubClient.connect(), subClient.connect()]).then(() => {\n  io.listen(3000);\n});\n')),(0,r.kt)("h4",{id:"serverattachhttpserver-options"},"server.attach(httpServer","[, options]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"httpServer")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/api/http.html#class-httpserver"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.Server>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/api/https.html#class-httpsserver"},(0,r.kt)("inlineCode",{parentName:"a"},"<https.Server>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"options")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("p",null,"Attaches the ",(0,r.kt)("inlineCode",{parentName:"p"},"Server")," to an ",(0,r.kt)("inlineCode",{parentName:"p"},"httpServer")," with the supplied ",(0,r.kt)("inlineCode",{parentName:"p"},"options"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { createServer } from "http";\nimport { Server } from "socket.io";\n\nconst httpServer = createServer();\nconst io = new Server();\n\nio.attach(httpServer);\n\nio.on("connection", (socket) => {\n  // ...\n});\n\nhttpServer.listen(3000);\n')),(0,r.kt)("h4",{id:"serverattachport-options"},"server.attach(port","[, options]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"port")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"options")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("p",null,"Attaches the ",(0,r.kt)("inlineCode",{parentName:"p"},"Server")," on the given ",(0,r.kt)("inlineCode",{parentName:"p"},"port")," with the supplied ",(0,r.kt)("inlineCode",{parentName:"p"},"options"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io";\n\nconst io = new Server();\n\nio.attach(3000);\n\nio.on("connection", (socket) => {\n  // ...\n});\n')),(0,r.kt)("h4",{id:"serverattachappapp-options"},"server.attachApp(app","[, options]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"app")," ",(0,r.kt)("a",{parentName:"li",href:"https://unetworking.github.io/uWebSockets.js/generated/interfaces/TemplatedApp.html"},(0,r.kt)("inlineCode",{parentName:"a"},"<uws.App>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"options")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("p",null,"Attaches the Socket.IO server to an ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/uNetworking/uWebSockets.js"}
1,"\xb5WebSockets.js")," app:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { App } from "uWebSockets.js";\nimport { Server } from "socket.io";\n\nconst app = App();\nconst io = new Server();\n\nio.attachApp(app);\n\nio.on("connection", (socket) => {\n  // ...\n});\n\napp.listen(3000, (token) => {\n  if (!token) {\n    console.warn("port already in use");\n  }\n});\n')),(0,r.kt)("h4",{id:"serverbindengine"},"server.bind(engine)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"engine")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<engine.Server>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"<Server>")))),(0,r.kt)("p",null,"Advanced use only. Binds the server to a specific engine.io ",(0,r.kt)("inlineCode",{parentName:"p"},"Server")," (or compatible API) instance."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { createServer } from "node:http";\nimport { Server as Engine } from "engine.io";\nimport { Server } from "socket.io";\n\nconst httpServer = createServer((req, res) => {\n  res.writeHead(404).end();\n});\n\nconst engine = new Engine();\n\nengine.attach(httpServer, {\n  path: "/socket.io/"\n});\n\nconst io = new Server();\n\nio.bind(engine);\n\nhttpServer.listen(3000);\n')),(0,r.kt)("h4",{id:"serverclosecallback"},"server.close(","[callback]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"callback")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Closes the Socket.IO server and disconnect all clients. The ",(0,r.kt)("inlineCode",{parentName:"p"},"callback")," argument is optional and will be called when all connections are closed."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This also closes the underlying HTTP server.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { createServer } from "http";\nimport { Server } from "socket.io";\n\nconst PORT = 3030;\nconst io = new Server(PORT);\n\nio.close();\n\nconst httpServer = createServer();\n\nhttpServer.listen(PORT); // PORT is free to use\n\nio.attach(httpServer);\n')),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Only closing the underlying HTTP server is not sufficient, as it will only prevent the server from accepting new connections but clients connected with WebSocket will not be disconnected right away."),(0,r.kt)("p",{parentName:"admonition"},"Reference: ",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org/api/http.html#serverclosecallback"},"https://nodejs.org/api/http.html#serverclosecallback"))),(0,r.kt)("h4",{id:"serverdisconnectsocketsclose"},"server.disconnectSockets(","[close]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("p",null,"Alias for ",(0,r.kt)("a",{parentName:"p",href:"#namespacedisconnectsocketsclose"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").disconnectSockets(close)')),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances disconnect\nio.disconnectSockets();\n\n// make all Socket instances in the "room1" room disconnect (and close the low-level connection)\nio.in("room1").disconnectSockets(true);\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This method also works within a cluster of multiple Socket.IO servers, with a compatible adapter like the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/postgres-adapter/"},"Postgres adapter"),"."),(0,r.kt)("p",{parentName:"admonition"},"In that case, if you only want to affect the socket instances on the given node, you need to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," flag:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// make all Socket instances that are currently connected on the given node disconnect\nio.local.disconnectSockets();\n"))),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-instance/#utility-methods"},"here"),"."),(0,r.kt)("h4",{id:"serveremiteventname-args"},"server.emit(eventName","[, ...args]",")"),(0,r.kt)("details",{className:"changelog"},(0,r.kt)("summary",null,"History"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Version"),(0,r.kt)("th",{parentName:"tr",align:null},"Changes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v4.5.0"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"io.emit()")," now supports acknowledgements.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Initial implementation."))))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"any[]")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"true"))),(0,r.kt)("p",null,"Emits an event to all connected clients in the main namespace."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.emit("hello");\n')),(0,r.kt)("p",null,"Any number of parameters can be included, and all serializable data structures are supported:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.emit("hello", 1, "2", { "3": 4 }, Buffer.from([5]));\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("hello", (arg1, arg2, arg3, arg4) => {\n  console.log(arg1); // 1\n  console.log(arg2); // "2"\n  console.log(arg3); // { "3": 4 }\n  console.log(arg4); // ArrayBuffer or Buffer, depending on the platform\n});\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The arguments will automatically be serialized, so calling ",(0,r.kt)("inlineCode",{parentName:"p"},"JSON.stringify()")," is not needed.")),(0,r.kt)("p",null,"You can use ",(0,r.kt)("a",{parentName:"p",href:"#servertoroom"},(0,r.kt)("inlineCode",{parentName:"a"},"to()"))," and ",(0,r.kt)("a",{parentName:"p",href:"#serverexceptrooms"},(0,r.kt)("inlineCode",{parentName:"a"},"except()"))," to send the packet to specific clients:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// the \u201chello\u201d event will be broadcast to all connected clients that are either\n// in the "room1" room or in the "room2" room, excluding those in the "room3" room\nio.to("room1").to("room2").except("room3").emit("hello");\n')),(0,r.kt)("p",null,"Starting with version ",(0,r.kt)("inlineCode",{parentName:"p"},"4.5.0"),", it is now possible to use acknowledgements when broadcasting:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.timeout(10000).emit("some-event", (err, responses) => {\n  if (err) {\n    // some clients did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per client\n  }\n});\n')),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Calling ",(0,r.kt)("a",{parentName:"p",href:"#servertimeoutvalue"},(0,r.kt)("inlineCode",{parentName:"a"},"timeout()"))," is mandatory in that case.")),(0,r.kt)("h4",{id:"serveremitwithackeventname-args"},"server.emitWithAck(eventName","[, ...args]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"any[]")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"},(0,r.kt)("inlineCode",{parentName:"a"},"Promise<any[]>")))),(0,r.kt)("p",null,"Promised-based version of broadcasting and expecting an acknowledgement from all targeted clients:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'try {\n  const responses = await io.timeout(10000).emitWithAck("some-event");\n  console.log(responses); // one response per client\n} catch (e) {\n  // some clients did not acknowledge the event in the given delay\n}\n')),(0,r.kt)("p",null,"The example above is equivalent to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.timeout(10000).emit("some-event", (err, responses) => {\n  if (err) {\n    // some clients did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per client\n  }\n});\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("some-event", (callback) => {\n  callback("got it"); // only one argument is expected\n});\n')),(0,r.kt)("h4",{id:"serverexceptrooms"},"server.except(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"rooms")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator"))),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to clients that have not joined the given ",(0,r.kt)("inlineCode",{parentName:"p"},"rooms"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room\nio.except("room-101").emit("foo", "bar");\n\n// with an array of rooms\nio.except(["room-101", "room-102"]).emit("foo", "bar");\n\n// with multiple chained calls\nio.except("room-101").except("room-102").emit("foo", "bar");\n')),(0,r.kt)("h4",{id:"serverfetchsockets"},"server.fetchSockets()"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("p",null,"Alias for ",(0,r.kt)("a",{parentName:"p",href:"#namespacefetchsockets"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").fetchSocket()')),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// return all Socket instances of the main namespace\nconst sockets = await io.fetchSockets();\n\n// return all Socket instances in the "room1" room of the main namespace\nconst sockets = await io.in("room1").fetchSockets();\n')),(0,r.kt)("p",null,"Sample usage:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  const userId = computeUserId(socket);\n\n  socket.join(userId);\n\n  socket.on("disconnect", async () => {\n    const sockets = await io.in(userId).fetchSockets();\n    if (sockets.length === 0) {\n      // no more active connections for the given user\n    }\n  });\n});\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This method also works within a cluster of multiple Socket.IO servers, with a compatible adapter like the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/postgres-adapter/"},"Postgres adapter"),"."),(0,r.kt)("p",{parentName:"admonition"},"In that case, if you only want to return the socket instances on the given node, you need to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," flag:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// return all Socket instances that are currently connected on the given node\nconst sockets = await io.local.fetchSockets();\n"))),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-instance/#utility-methods"},"here"),"."),(0,r.kt)("h4",{id:"serverinroom"},"server.in(room)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#servertoroom"},"server.to(room)"),", but might feel clearer in some cases:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// disconnect all clients in the "room-101" room\nio.in("room-101").disconnectSockets();\n')),(0,r.kt)("h4",{id:"serverlistenhttpserver-options"},"server.listen(httpServer","[, options]",")"),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#serverattachhttpserver-options"},"server.attach(httpServer[, options])"),"."),(0,r.kt)("h4",{id:"serverlistenport-options"},"server.listen(port","[, options]",")"),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#serverattachport-options"},"server.attach(port[, options])"),"."),(0,r.kt)("h4",{id:"serverofnsp"},"server.of(nsp)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"nsp")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp"},(0,r.kt)("inlineCode",{parentName:"a"},"<RegExp>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#namespace"},(0,r.kt)("inlineCode",{parentName:"a"},"<Namespace>")))),(0,r.kt)("p",null,"Initializes and retrieves the given ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace")," by its pathname identifier ",(0,r.kt)("inlineCode",{parentName:"p"},"nsp"),". If the namespace was already initialized it returns it immediately."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const adminNamespace = io.of("/admin");\n')),(0,r.kt)("p",null,"A regex or a function can also be provided, in order to create namespace in a dynamic way:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const dynamicNsp = io.of(/^\\/dynamic-\\d+$/).on("connection", (socket) => {\n  const newNamespace = socket.nsp; // newNamespace.name === "/dynamic-101"\n\n  // broadcast to all clients in the given sub-namespace\n  newNamespace.emit("hello");\n});\n\n// client-side\nconst socket = io("/dynamic-101");\n\n// broadcast to all clients in each sub-namespace\ndynamicNsp.emit("hello");\n\n// use a middleware for each sub-namespace\ndynamicNsp.use((socket, next) => { /* ... */ });\n')),(0,r.kt)("p",null,"With a function:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of((name, query, next) => {\n  // the checkToken method must return a boolean, indicating whether the client is able to connect or not.\n  next(null, checkToken(query.token));\n}).on("connection", (socket) => { /* ... */ });\n')),(0,r.kt)("h4",{id:"serveroneventname-listener"},"server.on(eventName, listener)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Inherited from the ",(0,r.kt)("a",{parentName:"em",href:"https://nodejs.org/api/events.html#class-eventemitter"},"EventEmitter class"),".")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"listener")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"<Server>")))),(0,r.kt)("p",null,"Adds the ",(0,r.kt)("inlineCode",{parentName:"p"},"listener")," function to the end of the listeners array for the event named ",(0,r.kt)("inlineCode",{parentName:"p"},"eventName"),"."),(0,r.kt)("p",null,"Available events:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#event-connection"},(0,r.kt)("inlineCode",{parentName:"a"},"connection"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#event-new_namespace"},(0,r.kt)("inlineCode",{parentName:"a"},"new_namespace"))),(0,r.kt)("li",{parentName:"ul"},"any custom event from the ",(0,r.kt)("a",{parentName:"li",href:"#namespaceserversideemiteventname-args"},(0,r.kt)("inlineCode",{parentName:"a"},"serverSideEmit"))," method")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  // ...\n});\n')),(0,r.kt)("h4",{id:"serveronconnectionsocket"},"server.onconnection(socket)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"socket")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<engine.Socket>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"<Server>")))),(0,r.kt)("p",null,"Advanced use only. Creates a new ",(0,r.kt)("inlineCode",{parentName:"p"},"socket.io")," client from the incoming engine.io (or compatible API) ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io";\nimport { Server as Engine } from "engine.io";\n\nconst engine = new Engine();\nconst io = new Server();\n\nengine.on("connection", (socket) => {\n  io.onconnection(socket);\n});\n\nengine.listen(3000);\n')),(0,r.kt)("h4",{id:"serverpathvalue"},"server.path(","[value]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"<Server>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>")))),(0,r.kt)("p",null,"Sets the path ",(0,r.kt)("inlineCode",{parentName:"p"},"value")," under which ",(0,r.kt)("inlineCode",{parentName:"p"},"engine.io")," and the static files will be served. Defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"/socket.io/"),". If no arguments are supplied this method returns the current value."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io";\n\nconst io = new Server();\n\nio.path("/myownpath/");\n')),(0,r.kt)("admonition",{type:"warning"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"path")," value must match the one on the client side:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { io } from "socket.io-client";\n\nconst socket = io({\n  path: "/myownpath/"\n});\n'))),(0,r.kt)("h4",{id:"serverserveclientvalue"},"server.serveClient(","[value]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"<Server>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>")))),(0,r.kt)("p",null,"If ",(0,r.kt)("inlineCode",{parentName:"p"},"value")," is ",(0,r.kt)("inlineCode",{parentName:"p"},"true")," the attached server will serve the client files. Defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),". This method has no effect after ",(0,r.kt)("inlineCode",{parentName:"p"},"listen")," is called. If no arguments are supplied this method returns the current value."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { Server } from "socket.io";\n\nconst io = new Server();\n\nio.serveClient(false);\n\nio.listen(3000);\n')),(0,r.kt)("h4",{id:"serverserversideemiteventname-args"},"server.serverSideEmit(eventName","[, ...args][, ack]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.1.0")),(0,r.kt)("p",null,"Alias for: ",(0,r.kt)("a",{parentName:"p",href:"#namespaceserversideemiteventname-args"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").serverSideEmit(/* ... */);'))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<any[]>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"ack")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"true"))),(0,r.kt)("p",null,"Sends a message to the other Socket.IO servers of the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/using-multiple-nodes/"},"cluster"),"."),(0,r.kt)("p",null,"Syntax:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.serverSideEmit("hello", "world");\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("hello", (arg1) => {\n  console.log(arg1); // prints "world"\n});\n')),(0,r.kt)("p",null,"Acknowledgements are supported too:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// server A\nio.serverSideEmit("ping", (err, responses) => {\n  console.log(responses[0]); // prints "pong"\n});\n\n// server B\nio.on("ping", (cb) => {\n  cb("pong");\n});\n')),(0,r.kt)("p",null,"Notes:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"the ",(0,r.kt)("inlineCode",{parentName:"p"},"connection"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"connect")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"new_namespace")," strings are reserved and cannot be used in your application.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"you can send any number of arguments, but binary structures are currently not supported (the array of arguments will be ",(0,r.kt)("inlineCode",{parentName:"p"},"JSON.stringify"),"-ed)"))),(0,r.kt)("p",null,"Example:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.serverSideEmit("hello", "world", 1, "2", { 3: "4" });\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"the acknowledgement callback might be called with an error, if the other Socket.IO servers do not respond after a given delay")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"io.serverSideEmit(\"ping\", (err, responses) => {\n  if (err) {\n    // at least one Socket.IO server has not responded\n    // the 'responses' array contains all the responses already received though\n  } else {\n    // success! the 'responses' array contains one object per other Socket.IO server in the cluster\n  }\n});\n")),(0,r.kt)("h4",{id:"serverserversideemitwithackeventname-args"},"server.serverSideEmitWithAck(eventName","[, ...args]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("p",null,"Alias for: ",(0,r.kt)("a",{parentName:"p",href:"#namespaceserversideemitwithackeventname-args"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").serverSideEmitWithAck(/* ... */);'))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<any[]>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"ack")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"},(0,r.kt)("inlineCode",{parentName:"a"},"Promise<any[]>")))),(0,r.kt)("p",null,"Promised-based version of broadcasting and expecting an acknowledgement from the other Socket.IO servers of the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/using-multiple-nodes/"},"cluster"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'try {\n  const responses = await io.serverSideEmitWithAck("some-event");\n  console.log(responses); // one response per server (except itself)\n} catch (e) {\n  // some servers did not acknowledge the event in the given delay\n}\n')),(0,r.kt)("p",null,"The example above is equivalent to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.serverSideEmit("some-event", (err, responses) => {\n  if (err) {\n    // some servers did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per server (except itself)\n  }\n});\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("some-event", (callback) => {\n  callback("got it"); // only one argument is expected\n});\n')),(0,r.kt)("h4",{id:"serversocketsjoinrooms"},"server.socketsJoin(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("p",null,"Alias for ",(0,r.kt)("a",{parentName:"p",href:"#namespacesocketsjoinrooms"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").socketsJoin(rooms)')),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances join the "room1" room\nio.socketsJoin("room1");\n\n// make all Socket instances in the "room1" room join the "room2" and "room3" rooms\nio.in("room1").socketsJoin(["room2", "room3"]);\n\n// this also works with a single socket ID\nio.in(theSocketId).socketsJoin("room1");\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This method also works within a cluster of multiple Socket.IO servers, with a compatible adapter like the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/postgres-adapter/"},"Postgres adapter"),"."),(0,r.kt)("p",{parentName:"admonition"},"In that case, if you only want to affect the socket instances on the given node, you need to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," flag:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances that are currently connected on the given node join the "room1" room\nio.local.socketsJoin("room1");\n'))),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-instance/#utility-methods"},"here"),"."),(0,r.kt)("h4",{id:"serversocketsleaverooms"},"server.socketsLeave(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("p",null,"Alias for ",(0,r.kt)("a",{parentName:"p",href:"#namespacesocketsleaverooms"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").socketsLeave(rooms)')),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances leave the "room1" room\nio.socketsLeave("room1");\n\n// make all Socket instances in the "room1" room leave the "room2" and "room3" rooms\nio.in("room1").socketsLeave(["room2", "room3"]);\n\n// this also works with a single socket ID\nio.in(theSocketId).socketsLeave("room1");\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This method also works within a cluster of multiple Socket.IO servers, with a compatible adapter like the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/postgres-adapter/"},"Postgres adapter"),"."),(0,r.kt)("p",{parentName:"admonition"},"In that case, if you only want to affect the socket instances on the given node, you need to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"local")," flag:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances that are currently connected on the given node leave the "room1" room\nio.local.socketsLeave("room1");\n'))),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-instance/#utility-methods"},"here"),"."),(0,r.kt)("h4",{id:"servertimeoutvalue"},"server.timeout(value)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator"))),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the callback will be called with an error when the\ngiven number of milliseconds have elapsed without an acknowledgement from all targeted clients:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.timeout(10000).emit("some-event", (err, responses) => {\n  if (err) {\n    // some clients did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per client\n  }\n});\n')),(0,r.kt)("h4",{id:"servertoroom"},"server.to(room)"),(0,r.kt)("details",{className:"changelog"},(0,r.kt)("summary",null,"History"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Version"),(0,r.kt)("th",{parentName:"tr",align:null},"Changes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v4.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Allow to pass an array of rooms.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Initial implementation."))))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"room")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator")," for chaining")),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to clients that have joined the given ",(0,r.kt)("inlineCode",{parentName:"p"},"room"),"."),(0,r.kt)("p",null,"To emit to multiple rooms, you can call ",(0,r.kt)("inlineCode",{parentName:"p"},"to")," several times."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// the \u201cfoo\u201d event will be broadcast to all connected clients in the \u201croom-101\u201d room\nio.to("room-101").emit("foo", "bar");\n\n// with an array of rooms (a client will be notified at most once)\nio.to(["room-101", "room-102"]).emit("foo", "bar");\n\n// with multiple chained calls\nio.to("room-101").to("room-102").emit("foo", "bar");\n')),(0,r.kt)("h4",{id:"serverusefn"},"server.use(fn)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("p",null,"Alias for ",(0,r.kt)("a",{parentName:"p",href:"#namespaceusefn"},(0,r.kt)("inlineCode",{parentName:"a"},'io.of("/").use(fn)')),"."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"fn")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Registers a middleware for the main namespace, which is a function that gets executed for every incoming ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket"),", and receives as parameters the socket and a function to optionally defer execution to the next registered middleware."),(0,r.kt)("p",null,"Errors passed to middleware callbacks are sent as special ",(0,r.kt)("inlineCode",{parentName:"p"},"connect_error")," packets to clients."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Server")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.use((socket, next) => {\n  const err = new Error("not authorized");\n  err.data = { content: "Please retry later" }; // additional details\n  next(err);\n});\n')),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Client")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("connect_error", err => {\n  console.log(err instanceof Error); // true\n  console.log(err.message); // not authorized\n  console.log(err.data); // { content: "Please retry later" }\n});\n')),(0,r.kt)("p",null,"More information can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/middlewares/"},"here"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you are looking for Express middlewares, please check ",(0,r.kt)("a",{parentName:"p",href:"#engineusemiddleware"},"this section"),".")),(0,r.kt)("h2",{id:"namespace"},"Namespace"),(0,r.kt)(o.Z,{alt:"Namespace in the class diagram for the server",sources:{light:(0,l.Z)("/images/server-class-diagram-namespace.png"),dark:(0,l.Z)("/images/server-class-diagram-namespace-dark.png")},mdxType:"ThemedImage"}),(0,r.kt)("p",null,"Represents a pool of sockets connected under a given scope identified by a pathname (eg: ",(0,r.kt)("inlineCode",{parentName:"p"},"/chat"),")."),(0,r.kt)("p",null,"More information can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/namespaces/"},"here"),"."),(0,r.kt)("h3",{id:"attributes-1"},"Attributes"),(0,r.kt)("h4",{id:"namespaceadapter"},"namespace.adapter"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/v4/adapter/"},(0,r.kt)("inlineCode",{parentName:"a"},"<Adapter>")))),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/glossary/#adapter"},'"Adapter"')," used for the namespace."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note:")," the adapter of the main namespace can be accessed with ",(0,r.kt)("inlineCode",{parentName:"p"},'io.of("/").adapter'),"."),(0,r.kt)("p",null,"More information about it ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/adapter/"},"here"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const adapter = io.of("/my-namespace").adapter;\n')),(0,r.kt)("h4",{id:"namespacename"},"namespace.name"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>")))),(0,r.kt)("p",null,"The namespace identifier property."),(0,r.kt)("h4",{id:"namespacesockets"},"namespace.sockets"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map"},(0,r.kt)("inlineCode",{parentName:"a"},"Map<SocketId, Socket>")))),(0,r.kt)("p",null,"A map of ",(0,r.kt)("a",{parentName:"p",href:"#socket"},"Socket")," instances that are connected to this namespace."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// number of sockets in this namespace (on this node)\nconst socketCount = io.of("/admin").sockets.size;\n')),(0,r.kt)("h3",{id:"events-1"},"Events"),(0,r.kt)("h4",{id:"event-connect-1"},"Event: 'connect'"),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#event-connection-1"},'Event: "connection"'),"."),(0,r.kt)("h4",{id:"event-connection-1"},"Event: 'connection'"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"socket")," ",(0,r.kt)("a",{parentName:"li",href:"#socket"},(0,r.kt)("inlineCode",{parentName:"a"},"<Socket>")))),(0,r.kt)("p",null,"Fired upon a connection from client."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// main namespace\nio.on("connection", (socket) => {\n  // ...\n});\n\n// custom namespace\nio.of("/admin").on("connection", (socket) => {\n  // ...\n});\n')),(0,r.kt)("h3",{id:"methods-1"},"Methods"),(0,r.kt)("h4",{id:"namespaceallsockets"},"namespace.allSockets()"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"Promise<Set<SocketId>>"))),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"This method will be removed in the next major release, please use ",(0,r.kt)("a",{parentName:"p",href:"#namespaceserversideemiteventname-args"},(0,r.kt)("inlineCode",{parentName:"a"},"serverSideEmit()"))," or ",(0,r.kt)("a",{parentName:"p",href:"#namespacefetchsockets"},(0,r.kt)("inlineCode",{parentName:"a"},"fetchSockets()"))," instead. ")),(0,r.kt)("p",null,"Gets a list of socket IDs connected to this namespace (across all nodes if applicable)."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// all sockets in the main namespace\nconst ids = await io.allSockets();\n\n// all sockets in the main namespace and in the "user:1234" room\nconst ids = await io.in("user:1234").allSockets();\n\n// all sockets in the "chat" namespace\nconst ids = await io.of("/chat").allSockets();\n\n// all sockets in the "chat" namespace and in the "general" room\nconst ids = await io.of("/chat").in("general").allSockets();\n')),(0,r.kt)("h4",{id:"namespacedisconnectsocketsclose"},"namespace.disconnectSockets(","[close]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"close")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>"))," whether to close the underlying connection"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"void"))),(0,r.kt)("p",null,"Makes the matching Socket instances disconnect."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances disconnect\nio.disconnectSockets();\n\n// make all Socket instances in the "room1" room disconnect (and discard the low-level connection)\nio.in("room1").disconnectSockets(true);\n\n// make all Socket instances in the "room1" room of the "admin" namespace disconnect\nio.of("/admin").in("room1").disconnectSockets();\n\n// this also works with a single socket ID\nio.of("/admin").in(theSocketId).disconnectSockets();\n')),(0,r.kt)("h4",{id:"namespaceemiteventname-args"},"namespace.emit(eventName","[, ...args]",")"),(0,r.kt)("details",{className:"changelog"},(0,r.kt)("summary",null,"History"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Version"),(0,r.kt)("th",{parentName:"tr",align:null},"Changes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v4.5.0"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"io.emit()")," now supports acknowledgements.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Initial implementation."))))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"any[]")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"true"))),(0,r.kt)("p",null,"Emits an event to all connected clients in the given namespace."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").emit("hello");\n')),(0,r.kt)("p",null,"Any number of parameters can be included, and all serializable data structures are supported:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").emit("hello", 1, "2", { "3": 4 }, Buffer.from([5]));\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("hello", (arg1, arg2, arg3, arg4) => {\n  console.log(arg1); // 1\n  console.log(arg2); // "2"\n  console.log(arg3); // { "3": 4 }\n  console.log(arg4); // ArrayBuffer or Buffer, depending on the platform\n});\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"The arguments will automatically be serialized, so calling ",(0,r.kt)("inlineCode",{parentName:"p"},"JSON.stringify()")," is not needed.")),(0,r.kt)("p",null,"You can use ",(0,r.kt)("a",{parentName:"p",href:"#namespacetoroom"},(0,r.kt)("inlineCode",{parentName:"a"},"to()"))," and ",(0,r.kt)("a",{parentName:"p",href:"#namespaceexceptrooms"},(0,r.kt)("inlineCode",{parentName:"a"},"except()"))," to send the packet to specific clients:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// the \u201chello\u201d event will be broadcast to all connected clients that are either\n// in the "room1" room or in the "room2" room, excluding those in the "room3" room\nio.of("/chat").to("room1").to("room2").except("room3").emit("hello");\n')),(0,r.kt)("p",null,"Starting with version ",(0,r.kt)("inlineCode",{parentName:"p"},"4.5.0"),", it is now possible to use acknowledgements when broadcasting:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").timeout(10000).emit("some-event", (err, responses) => {\n  if (err) {\n    // some clients did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per client\n  }\n});\n')),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Calling ",(0,r.kt)("a",{parentName:"p",href:"#namespacetimeoutvalue"},(0,r.kt)("inlineCode",{parentName:"a"},"timeout()"))," is mandatory in that case.")),(0,r.kt)("h4",{id:"namespaceemitwithackeventname-args"},"namespace.emitWithAck(eventName","[, ...args]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"any[]")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"},(0,r.kt)("inlineCode",{parentName:"a"},"Promise<any[]>")))),(0,r.kt)("p",null,"Promised-based version of broadcasting and expecting an acknowledgement from all targeted clients in the given namespace:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'try {\n  const responses = await io.of("/chat").timeout(10000).emitWithAck("some-event");\n  console.log(responses); // one response per client\n} catch (e) {\n  // some clients did not acknowledge the event in the given delay\n}\n')),(0,r.kt)("p",null,"The example above is equivalent to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").timeout(10000).emit("some-event", (err, responses) => {\n  if (err) {\n    // some clients did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per client\n  }\n});\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("some-event", (callback) => {\n  callback("got it"); // only one argument is expected\n});\n')),(0,r.kt)("h4",{id:"namespaceexceptrooms"},"namespace.except(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"rooms")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator"))),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to clients that have not joined the given ",(0,r.kt)("inlineCode",{parentName:"p"},"rooms"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const myNamespace = io.of("/my-namespace");\n\n// the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room\nmyNamespace.except("room-101").emit("foo", "bar");\n\n// with an array of rooms\nmyNamespace.except(["room-101", "room-102"]).emit("foo", "bar");\n\n// with multiple chained calls\nmyNamespace.except("room-101").except("room-102").emit("foo", "bar");\n')),(0,r.kt)("h4",{id:"namespacefetchsockets"},"namespace.fetchSockets()"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#socket"},(0,r.kt)("inlineCode",{parentName:"a"},"Socket[]"))," | ",(0,r.kt)("inlineCode",{parentName:"li"},"RemoteSocket[]"))),(0,r.kt)("p",null,"Returns the matching Socket instances:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// return all Socket instances in the main namespace\nconst sockets = await io.fetchSockets();\n\n// return all Socket instances in the "room1" room of the main namespace\nconst sockets = await io.in("room1").fetchSockets();\n\n// return all Socket instances in the "room1" room of the "admin" namespace\nconst sockets = await io.of("/admin").in("room1").fetchSockets();\n\n// this also works with a single socket ID\nconst sockets = await io.in(theSocketId).fetchSockets();\n')),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"sockets")," variable in the example above is an array of objects exposing a subset of the usual Socket class:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"for (const socket of sockets) {\n  console.log(socket.id);\n  console.log(socket.handshake);\n  console.log(socket.rooms);\n  console.log(socket.data);\n  socket.emit(/* ... */);\n  socket.join(/* ... */);\n  socket.leave(/* ... */);\n  socket.disconnect(/* ... */);\n}\n")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"data")," attribute is an arbitrary object that can be used to share information between Socket.IO servers:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// server A\nio.on("connection", (socket) => {\n  socket.data.username = "alice";\n});\n\n// server B\nconst sockets = await io.fetchSockets();\nconsole.log(sockets[0].data.username); // "alice"\n')),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Important note"),": this method (and ",(0,r.kt)("inlineCode",{parentName:"p"},"socketsJoin"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"socketsLeave")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"disconnectSockets")," too) is compatible with the Redis adapter (starting with ",(0,r.kt)("inlineCode",{parentName:"p"},"[email protected]"),"), which means that they will work across Socket.IO servers."),(0,r.kt)("h4",{id:"namespaceinroom"},"namespace.in(room)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#namespacetoroom"},"namespace.to(room)"),", but might feel clearer in some cases:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const myNamespace = io.of("/my-namespace");\n\n// disconnect all clients in the "room-101" room\nmyNamespace.in("room-101").disconnectSockets();\n')),(0,r.kt)("h4",{id:"namespaceserversideemiteventname-args"},"namespace.serverSideEmit(eventName","[, ...args][, ack]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.1.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<any[]>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"ack")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"true"))),(0,r.kt)("p",null,"Sends a message to the other Socket.IO servers of the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/using-multiple-nodes/"},"cluster"),"."),(0,r.kt)("p",null,"Syntax:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").serverSideEmit("hello", "world");\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").on("hello", (arg1) => {\n  console.log(arg1); // prints "world"\n});\n')),(0,r.kt)("p",null,"Acknowledgements are supported too:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// server A\nio.of("/chat").serverSideEmit("ping", (err, responses) => {\n  console.log(responses[0]); // prints "pong"\n});\n\n// server B\nio.of("/chat").on("ping", (cb) => {\n  cb("pong");\n});\n')),(0,r.kt)("p",null,"Notes:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"the ",(0,r.kt)("inlineCode",{parentName:"p"},"connection"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"connect")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"new_namespace")," strings are reserved and cannot be used in your application.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"you can send any number of arguments, but binary structures are currently not supported (the array of arguments will be ",(0,r.kt)("inlineCode",{parentName:"p"},"JSON.stringify"),"-ed)"))),(0,r.kt)("p",null,"Example:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").serverSideEmit("hello", "world", 1, "2", { 3: "4" });\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"the acknowledgement callback might be called with an error, if the other Socket.IO servers do not respond after a given delay")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"io.of(\"/chat\").serverSideEmit(\"ping\", (err, responses) => {\n  if (err) {\n    // at least one Socket.IO server has not responded\n    // the 'responses' array contains all the responses already received though\n  } else {\n    // success! the 'responses' array contains one object per other Socket.IO server in the cluster\n  }\n});\n")),(0,r.kt)("h4",{id:"namespaceserversideemitwithackeventname-args"},"namespace.serverSideEmitWithAck(eventName","[, ...args]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<any[]>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"ack")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"},(0,r.kt)("inlineCode",{parentName:"a"},"Promise<any[]>")))),(0,r.kt)("p",null,"Promised-based version of broadcasting and expecting an acknowledgement from the other Socket.IO servers of the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/using-multiple-nodes/"},"cluster"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'try {\n  const responses = await io.of("/chat").serverSideEmitWithAck("some-event");\n  console.log(responses); // one response per server (except itself)\n} catch (e) {\n  // some servers did not acknowledge the event in the given delay\n}\n')),(0,r.kt)("p",null,"The example above is equivalent to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").serverSideEmit("some-event", (err, responses) => {\n  if (err) {\n    // some servers did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per server (except itself)\n  }\n});\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").on("some-event", (callback) => {\n  callback("got it"); // only one argument is expected\n});\n')),(0,r.kt)("h4",{id:"namespacesocketsjoinrooms"},"namespace.socketsJoin(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"rooms")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"void"))),(0,r.kt)("p",null,"Makes the matching Socket instances join the specified rooms:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances join the "room1" room\nio.socketsJoin("room1");\n\n// make all Socket instances in the "room1" room join the "room2" and "room3" rooms\nio.in("room1").socketsJoin(["room2", "room3"]);\n\n// make all Socket instances in the "room1" room of the "admin" namespace join the "room2" room\nio.of("/admin").in("room1").socketsJoin("room2");\n\n// this also works with a single socket ID\nio.in(theSocketId).socketsJoin("room1");\n')),(0,r.kt)("p",null,"More information can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-instance/#utility-methods"},"here"),"."),(0,r.kt)("h4",{id:"namespacesocketsleaverooms"},"namespace.socketsLeave(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"rooms")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"void"))),(0,r.kt)("p",null,"Makes the matching Socket instances leave the specified rooms:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// make all Socket instances leave the "room1" room\nio.socketsLeave("room1");\n\n// make all Socket instances in the "room1" room leave the "room2" and "room3" rooms\nio.in("room1").socketsLeave(["room2", "room3"]);\n\n// make all Socket instances in the "room1" room of the "admin" namespace leave the "room2" room\nio.of("/admin").in("room1").socketsLeave("room2");\n\n// this also works with a single socket ID\nio.in(theSocketId).socketsLeave("room1");\n')),(0,r.kt)("h4",{id:"namespacetimeoutvalue"},"namespace.timeout(value)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator"))),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the callback will be called with an error when the\ngiven number of milliseconds have elapsed without an acknowledgement from the client:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").timeout(10000).emit("some-event", (err, responses) => {\n  if (err) {\n    // some clients did not acknowledge the event in the given delay\n  } else {\n    console.log(responses); // one response per client\n  }\n});\n')),(0,r.kt)("h4",{id:"namespacetoroom"},"namespace.to(room)"),(0,r.kt)("details",{className:"changelog"},(0,r.kt)("summary",null,"History"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Version"),(0,r.kt)("th",{parentName:"tr",align:null},"Changes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v4.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Allow to pass an array of rooms.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Initial implementation."))))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"room")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator")," for chaining")),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to clients that have joined the given ",(0,r.kt)("inlineCode",{parentName:"p"},"room"),"."),(0,r.kt)("p",null,"To emit to multiple rooms, you can call ",(0,r.kt)("inlineCode",{parentName:"p"},"to")," several times."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const myNamespace = io.of("/my-namespace");\n\n// the \u201cfoo\u201d event will be broadcast to all connected clients in the \u201croom-101\u201d room\nmyNamespace.to("room-101").emit("foo", "bar");\n\n// with an array of rooms (a client will be notified at most once)\nmyNamespace.to(["room-101", "room-102"]).emit("foo", "bar");\n\n// with multiple chained calls\nmyNamespace.to("room-101").to("room-102").emit("foo", "bar");\n')),(0,r.kt)("h4",{id:"namespaceusefn"},"namespace.use(fn)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"fn")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Registers a middleware for the given namespace, which is a function that gets executed for every incoming ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket"),", and receives as parameters the socket and a function to optionally defer execution to the next registered middleware."),(0,r.kt)("p",null,"Errors passed to middleware callbacks are sent as special ",(0,r.kt)("inlineCode",{parentName:"p"},"connect_error")," packets to clients."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Server")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/chat").use((socket, next) => {\n  const err = new Error("not authorized");\n  err.data = { content: "Please retry later" }; // additional details\n  next(err);\n});\n')),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Client")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("connect_error", err => {\n  console.log(err instanceof Error); // true\n  console.log(err.message); // not authorized\n  console.log(err.data); // { content: "Please retry later" }\n});\n')),(0,r.kt)("p",null,"More information can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/middlewares/"},"here"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you are looking for Express middlewares, please check ",(0,r.kt)("a",{parentName:"p",href:"#engineusemiddleware"},"this section"),".")),(0,r.kt)("h3",{id:"flags"},"Flags"),(0,r.kt)("h4",{id:"flag-local"},"Flag: 'local'"),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event data will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to the current node (when ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/using-multiple-nodes/"},"scaling to multiple nodes"),")."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.local.emit("an event", { some: "data" });\n')),(0,r.kt)("h4",{id:"flag-volatile"},"Flag: 'volatile'"),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event data may be lost if the clients are not ready to receive messages (because of network slowness or other issues, or because they\u2019re connected through long polling and is in the middle of a request-response cycle)."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.volatile.emit("an event", { some: "data" }); // the clients may or may not receive it\n')),(0,r.kt)("h2",{id:"socket"},"Socket"),(0,r.kt)(o.Z,{alt:"Socket in the class diagram for the server",sources:{light:(0,l.Z)("/images/server-class-diagram-socket.png"),dark:(0,l.Z)("/images/server-class-diagram-socket-dark.png")},mdxType:"ThemedImage"}),(0,r.kt)("p",null,"A ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," is the fundamental class for interacting with browser clients. A ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," belongs to a certain ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace")," (by default ",(0,r.kt)("inlineCode",{parentName:"p"},"/"),") and uses an underlying ",(0,r.kt)("inlineCode",{parentName:"p"},"Client")," to communicate."),(0,r.kt)("p",null,"It should be noted the ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," doesn't relate directly to the actual underlying TCP/IP ",(0,r.kt)("inlineCode",{parentName:"p"},"socket")," and it is only the name of the class."),(0,r.kt)("p",null,"Within each ",(0,r.kt)("inlineCode",{parentName:"p"},"Namespace"),", you can also define arbitrary channels (called ",(0,r.kt)("inlineCode",{parentName:"p"},"room"),") that the ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," can join and leave. That provides a convenient way to broadcast to a group of ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket"),"s (see ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket#to")," below)."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," class inherits from ",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org/api/events.html#events_class_eventemitter"},"EventEmitter"),". The ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," class overrides the ",(0,r.kt)("inlineCode",{parentName:"p"},"emit")," method, and does not modify any other ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter")," method. All methods documented here which also appear as ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter")," methods (apart from ",(0,r.kt)("inlineCode",{parentName:"p"},"emit"),") are implemented by ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter"),", and documentation for ",(0,r.kt)("inlineCode",{parentName:"p"}
1,"EventEmitter")," applies."),(0,r.kt)("p",null,"More information can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-socket-instance/"},"here"),"."),(0,r.kt)("h3",{id:"events-2"},"Events"),(0,r.kt)("h4",{id:"event-disconnect"},"Event: 'disconnect'"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"reason")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," the reason of the disconnection (either client or server-side)")),(0,r.kt)("p",null,"Fired upon disconnection."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.on("disconnect", (reason) => {\n    // ...\n  });\n});\n')),(0,r.kt)("p",null,"Possible reasons:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Reason"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"server namespace disconnect")),(0,r.kt)("td",{parentName:"tr",align:null},"The socket was forcefully disconnected with ",(0,r.kt)("a",{parentName:"td",href:"/docs/v4/server-api/#socketdisconnectclose"},"socket.disconnect()"),".")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"client namespace disconnect")),(0,r.kt)("td",{parentName:"tr",align:null},"The client has manually disconnected the socket using ",(0,r.kt)("a",{parentName:"td",href:"/docs/v4/client-api/#socketdisconnect"},"socket.disconnect()"),".")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"server shutting down")),(0,r.kt)("td",{parentName:"tr",align:null},"The server is, well, shutting down.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"ping timeout")),(0,r.kt)("td",{parentName:"tr",align:null},"The client did not send a PONG packet in the ",(0,r.kt)("inlineCode",{parentName:"td"},"pingTimeout")," delay.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"transport close")),(0,r.kt)("td",{parentName:"tr",align:null},"The connection was closed (example: the user has lost connection, or the network was changed from WiFi to 4G).")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"transport error")),(0,r.kt)("td",{parentName:"tr",align:null},"The connection has encountered an error.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"parse error")),(0,r.kt)("td",{parentName:"tr",align:null},"The server has received an invalid packet from the client.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"forced close")),(0,r.kt)("td",{parentName:"tr",align:null},"The server has received an invalid packet from the client.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"forced server close")),(0,r.kt)("td",{parentName:"tr",align:null},"The client did not join a namespace in time (see the ",(0,r.kt)("a",{parentName:"td",href:"/docs/v4/server-options/#connecttimeout"},(0,r.kt)("inlineCode",{parentName:"a"},"connectTimeout"))," option) and was forcefully closed.")))),(0,r.kt)("h4",{id:"event-disconnecting"},"Event: 'disconnecting'"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"reason")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," the reason of the disconnection (either client or server-side)")),(0,r.kt)("p",null,"Fired when the client is going to be disconnected (but hasn't left its ",(0,r.kt)("inlineCode",{parentName:"p"},"rooms")," yet)."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.on("disconnecting", (reason) => {\n    console.log(socket.rooms); // Set { ... }\n  });\n});\n')),(0,r.kt)("p",null,"With an asynchronous handler, you will need to create a copy of the ",(0,r.kt)("inlineCode",{parentName:"p"},"rooms")," attribute:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.on("disconnecting", async (reason) => {\n    const rooms = new Set(socket.rooms);\n\n    await someLongRunningOperation();\n\n    // socket.rooms will be empty there\n    console.log(rooms);\n  });\n});\n')),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Those events, along with ",(0,r.kt)("inlineCode",{parentName:"p"},"connect"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"connect_error"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"newListener")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"removeListener"),", are special events that shouldn't be used in your application:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// BAD, will throw an error\nsocket.emit("disconnect");\n'))),(0,r.kt)("h3",{id:"attributes-2"},"Attributes"),(0,r.kt)("h4",{id:"socketclient"},"socket.client"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#client"},(0,r.kt)("inlineCode",{parentName:"a"},"<Client>")))),(0,r.kt)("p",null,"A reference to the underlying ",(0,r.kt)("inlineCode",{parentName:"p"},"Client")," object."),(0,r.kt)("h4",{id:"socketconn"},"socket.conn"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"<engine.Socket>"))),(0,r.kt)("p",null,"A reference to the underlying ",(0,r.kt)("inlineCode",{parentName:"p"},"Client")," transport connection (engine.io ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," object). This allows access to the IO transport layer, which still (mostly) abstracts the actual TCP/IP socket."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  console.log("initial transport", socket.conn.transport.name); // prints "polling"\n\n  socket.conn.once("upgrade", () => {\n    // called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)\n    console.log("upgraded transport", socket.conn.transport.name); // prints "websocket"\n  });\n\n  socket.conn.on("packet", ({ type, data }) => {\n    // called for each packet received\n  });\n\n  socket.conn.on("packetCreate", ({ type, data }) => {\n    // called for each packet sent\n  });\n\n  socket.conn.on("drain", () => {\n    // called when the write buffer is drained\n  });\n\n  socket.conn.on("heartbeat", () => {\n    // called after each round trip of the heartbeat mechanism\n    console.log("heartbeat");\n  });\n\n  socket.conn.on("close", (reason) => {\n    // called when the underlying connection is closed\n  });\n});\n')),(0,r.kt)("h4",{id:"socketdata"},"socket.data"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("p",null,"An arbitrary object that can be used in conjunction with the ",(0,r.kt)("a",{parentName:"p",href:"#namespacefetchsockets"},(0,r.kt)("inlineCode",{parentName:"a"},"fetchSockets()"))," utility method:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.data.username = "alice";\n});\n\nconst sockets = await io.fetchSockets();\nconsole.log(sockets[0].data.username); // "alice"\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"This also works within a Socket.IO cluster, with a compatible adapter like the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/postgres-adapter/"},"Postgres adapter"),".")),(0,r.kt)("h4",{id:"sockethandshake"},"socket.handshake"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>")))),(0,r.kt)("p",null,"The handshake details:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Field"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"headers"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"IncomingHttpHeaders")),(0,r.kt)("td",{parentName:"tr",align:null},"The headers sent as part of the handshake.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"time"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("td",{parentName:"tr",align:null},"The date of creation (as string).")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"address"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("td",{parentName:"tr",align:null},"The ip address of the client.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"xdomain"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>"))),(0,r.kt)("td",{parentName:"tr",align:null},"Whether the connection is cross-domain.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"secure"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>"))),(0,r.kt)("td",{parentName:"tr",align:null},"Whether the connection is made over SSL.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"issued"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>"))),(0,r.kt)("td",{parentName:"tr",align:null},"The date of creation (as unix timestamp).")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"url"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("td",{parentName:"tr",align:null},"The request URL string.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"query"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Record<string, string or string[]>")),(0,r.kt)("td",{parentName:"tr",align:null},"The query parameters of the first request.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"auth"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Record<string, any>")),(0,r.kt)("td",{parentName:"tr",align:null},"The authentication payload. See also ",(0,r.kt)("a",{parentName:"td",href:"/docs/v4/middlewares/"},"here"),".")))),(0,r.kt)("p",null,"Usage:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.use((socket, next) => {\n  let handshake = socket.handshake;\n  // ...\n});\n\nio.on("connection", (socket) => {\n  let handshake = socket.handshake;\n  // ...\n});\n')),(0,r.kt)("p",null,"Example:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const handshake = {\n  headers: {\n    "user-agent": "node-XMLHttpRequest",\n    accept: "*/*",\n    host: "localhost:3000",\n    connection: "close"\n  },\n  time: "Wed Jan 01 2020 01:00:00 GMT+0100 (Central European Standard Time)",\n  address: "::ffff:127.0.0.1",\n  xdomain: false,\n  secure: false,\n  issued: 1577836800000,\n  url: "/socket.io/?EIO=4&transport=polling&t=OPAfXv5&b64=1",\n  query: {\n    EIO: "4",\n    transport: "polling",\n    t: "OPAfXv5",\n    b64: "1"\n  },\n  auth: {}\n}\n')),(0,r.kt)("p",null,"Note: the ",(0,r.kt)("inlineCode",{parentName:"p"},"headers")," attribute refers to the headers of the first HTTP request of the session, and won't be updated by the subsequent HTTP requests."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  console.log(socket.handshake.headers === socket.request.headers); // prints "true"\n});\n')),(0,r.kt)("h4",{id:"socketid"},"socket.id"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>")))),(0,r.kt)("p",null,"A unique identifier for the session, that comes from the underlying ",(0,r.kt)("inlineCode",{parentName:"p"},"Client"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"id")," attribute is an ",(0,r.kt)("strong",{parentName:"p"},"ephemeral")," ID that is not meant to be used in your application (or only for debugging purposes) because:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"this ID is regenerated after each reconnection (for example when the WebSocket connection is severed, or when the user refreshes the page)"),(0,r.kt)("li",{parentName:"ul"},"two different browser tabs will have two different IDs"),(0,r.kt)("li",{parentName:"ul"},"there is no message queue stored for a given ID on the server (i.e. if the client is disconnected, the messages sent from the server to this ID are lost)")),(0,r.kt)("p",{parentName:"admonition"},"Please use a regular session ID instead (either sent in a cookie, or stored in the localStorage and sent in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/client-options/#auth"},(0,r.kt)("inlineCode",{parentName:"a"},"auth"))," payload)."),(0,r.kt)("p",{parentName:"admonition"},"See also:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/get-started/private-messaging-part-2/"},"Part II of our private message guide")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/how-to/deal-with-cookies"},"How to deal with cookies")))),(0,r.kt)("h4",{id:"socketrecovered"},"socket.recovered"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>")))),(0,r.kt)("p",null,"Whether the connection state was successfully recovered during the last reconnection."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  if (socket.recovered) {\n    // recovery was successful: socket.id, socket.rooms and socket.data were restored\n  } else {\n    // new or unrecoverable session\n  }\n});\n')),(0,r.kt)("p",null,"More information about this feature ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/connection-state-recovery"},"here"),"."),(0,r.kt)("h4",{id:"socketrequest"},"socket.request"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/api/http.html#class-httpincomingmessage"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.IncomingMessage>")))),(0,r.kt)("p",null,"A getter proxy that returns the reference to the ",(0,r.kt)("inlineCode",{parentName:"p"},"request")," that originated the underlying engine.io ",(0,r.kt)("inlineCode",{parentName:"p"},"Client"),". Useful for accessing request headers such as ",(0,r.kt)("inlineCode",{parentName:"p"},"Cookie")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"User-Agent"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { parse } from "cookie";\n\nio.on("connection", (socket) => {\n  const cookies = parse(socket.request.headers.cookie || "");\n});\n')),(0,r.kt)("p",null,"Note: ",(0,r.kt)("inlineCode",{parentName:"p"},"socket.request")," refers to the first HTTP request of the session, and won't be updated by the subsequent HTTP requests."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  console.log(socket.request.headers === socket.handshake.headers); // prints "true"\n});\n')),(0,r.kt)("p",null,"If you don't need this reference, you can discard it in order to reduce the memory footprint:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  delete socket.conn.request;\n});\n')),(0,r.kt)("h4",{id:"socketrooms"},"socket.rooms"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set"},(0,r.kt)("inlineCode",{parentName:"a"},"Set<string>")))),(0,r.kt)("p",null,"A Set of strings identifying the rooms this client is in."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n\n  console.log(socket.rooms); // Set { <socket.id> }\n\n  socket.join("room1");\n\n  console.log(socket.rooms); // Set { <socket.id>, "room1" }\n\n});\n')),(0,r.kt)("h3",{id:"methods-2"},"Methods"),(0,r.kt)("h4",{id:"socketcompressvalue"},"socket.compress(value)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>"))," whether to following packet will be compressed"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"Socket")," for chaining")),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event data will only be ",(0,r.kt)("em",{parentName:"p"},"compressed")," if the value is ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),". Defaults to ",(0,r.kt)("inlineCode",{parentName:"p"}
1,"true")," when you don't call the method."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.compress(false).emit("uncompressed", "that\'s rough");\n});\n')),(0,r.kt)("h4",{id:"socketdisconnectclose"},"socket.disconnect(","[close]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"close")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<boolean>"))," whether to close the underlying connection"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#socket"},(0,r.kt)("inlineCode",{parentName:"a"},"Socket")))),(0,r.kt)("p",null,"Disconnects this socket. If value of close is ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", closes the underlying connection. Otherwise, it just disconnects the namespace."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  setTimeout(() => socket.disconnect(true), 5000);\n});\n')),(0,r.kt)("h4",{id:"socketemiteventname-args"},"socket.emit(eventName","[, ...args][, ack]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"(overrides ",(0,r.kt)("inlineCode",{parentName:"em"},"EventEmitter.emit"),")")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<any[]>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"ack")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"true"))),(0,r.kt)("p",null,"Emits an event to the socket identified by the string name. Any other parameters can be included. All serializable data structures are supported, including ",(0,r.kt)("inlineCode",{parentName:"p"},"Buffer"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", () => {\n  socket.emit("hello", "world");\n  socket.emit("with-binary", 1, "2", { 3: "4", 5: Buffer.from([6]) });\n});\n')),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"ack")," argument is optional and will be called with the client's answer."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Server")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.emit("hello", "world", (response) => {\n    console.log(response); // "got it"\n  });\n});\n')),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Client")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("hello", (arg, callback) => {\n  console.log(arg); // "world"\n  callback("got it");\n});\n')),(0,r.kt)("h4",{id:"socketemitwithackeventname-args"},"socket.emitWithAck(eventName","[, ...args]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"any[]")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"},(0,r.kt)("inlineCode",{parentName:"a"},"Promise<any>")))),(0,r.kt)("p",null,"Promised-based version of emitting and expecting an acknowledgement from the given client:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", async (socket) => {\n  // without timeout\n  const response = await socket.emitWithAck("hello", "world");\n\n  // with a specific timeout\n  try {\n    const response = await socket.timeout(10000).emitWithAck("hello", "world");\n  } catch (err) {\n    // the client did not acknowledge the event in the given delay\n  }\n});\n')),(0,r.kt)("p",null,"The example above is equivalent to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  // without timeout\n  socket.emit("hello", "world", (val) => {\n    // ...\n  });\n\n  // with a specific timeout\n  socket.timeout(10000).emit("hello", "world", (err, val) => {\n    // ...\n  });\n});\n')),(0,r.kt)("p",null,"And on the receiving side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("hello", (arg1, callback) => {\n  callback("got it"); // only one argument is expected\n});\n')),(0,r.kt)("h4",{id:"socketeventnames"},"socket.eventNames()"),(0,r.kt)("p",null,"Inherited from ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter")," (along with other methods not mentioned here). See the Node.js documentation for the ",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org/docs/latest/api/events.html"},"events")," module."),(0,r.kt)("h4",{id:"socketexceptrooms"},"socket.except(rooms)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"rooms")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"BroadcastOperator"))),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to clients that have not joined the given ",(0,r.kt)("inlineCode",{parentName:"p"},"rooms")," (the socket itself being excluded)."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'// to all clients except the ones in "room1" and the sender\nsocket.broadcast.except("room1").emit(/* ... */);\n\n// same as above\nsocket.except("room1").emit(/* ... */);\n\n// to all clients in "room4" except the ones in "room5" and the sender\nsocket.to("room4").except("room5").emit(/* ... */);\n')),(0,r.kt)("h4",{id:"socketinroom"},"socket.in(room)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("p",null,"Synonym of ",(0,r.kt)("a",{parentName:"p",href:"#sockettoroom"},"socket.to(room)"),"."),(0,r.kt)("h4",{id:"socketjoinroom"},"socket.join(room)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"room")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"void")," | ",(0,r.kt)("inlineCode",{parentName:"li"},"Promise"))),(0,r.kt)("p",null,"Adds the socket to the given ",(0,r.kt)("inlineCode",{parentName:"p"},"room")," or to the list of rooms."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.join("room 237");\n  \n  console.log(socket.rooms); // Set { <socket.id>, "room 237" }\n\n  socket.join(["room 237", "room 238"]);\n\n  io.to("room 237").emit("a new user has joined the room"); // broadcast to everyone in the room\n});\n')),(0,r.kt)("p",null,"The mechanics of joining rooms are handled by the ",(0,r.kt)("inlineCode",{parentName:"p"},"Adapter")," that has been configured (see ",(0,r.kt)("inlineCode",{parentName:"p"},"Server#adapter")," above), defaulting to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/socketio/socket.io-adapter"},"socket.io-adapter"),"."),(0,r.kt)("p",null,"For your convenience, each socket automatically joins a room identified by its id (see ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket#id"),"). This makes it easy to broadcast messages to other sockets:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.on("say to someone", (id, msg) => {\n    // send a private message to the socket with the given id\n    socket.to(id).emit("my message", msg);\n  });\n});\n')),(0,r.kt)("h4",{id:"socketleaveroom"},"socket.leave(room)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"room")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"void")," | ",(0,r.kt)("inlineCode",{parentName:"li"},"Promise"))),(0,r.kt)("p",null,"Removes the socket from the given ",(0,r.kt)("inlineCode",{parentName:"p"},"room"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.leave("room 237");\n\n  io.to("room 237").emit(`user ${socket.id} has left the room`);\n});\n')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Rooms are left automatically upon disconnection.")),(0,r.kt)("h4",{id:"socketlistenersany"},"socket.listenersAny()"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function[]>")))),(0,r.kt)("p",null,"Returns the list of registered catch-all listeners."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"const listeners = socket.listenersAny();\n")),(0,r.kt)("h4",{id:"socketlistenersanyoutgoing"},"socket.listenersAnyOutgoing()"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function[]>")))),(0,r.kt)("p",null,"Returns the list of registered catch-all listeners for outgoing packets."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"const listeners = socket.listenersAnyOutgoing();\n")),(0,r.kt)("h4",{id:"socketoffanylistener"},"socket.offAny(","[listener]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"listener")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Removes the previously registered listener. If no listener is provided, all catch-all listeners are removed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"const myListener = () => { /* ... */ };\n\nsocket.onAny(myListener);\n\n// then, later\nsocket.offAny(myListener);\n\nsocket.offAny();\n")),(0,r.kt)("h4",{id:"socketoffanyoutgoinglistener"},"socket.offAnyOutgoing(","[listener]",")"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"listener")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Removes the previously registered listener. If no listener is provided, all catch-all listeners are removed."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"const myListener = () => { /* ... */ };\n\nsocket.onAnyOutgoing(myListener);\n\n// remove a single listener\nsocket.offAnyOutgoing(myListener);\n\n// remove all listeners\nsocket.offAnyOutgoing();\n")),(0,r.kt)("h4",{id:"socketoneventname-callback"},"socket.on(eventName, callback)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Inherited from the ",(0,r.kt)("a",{parentName:"em",href:"https://nodejs.org/api/events.html#class-eventemitter"},"EventEmitter class"),".")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"eventName")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<symbol>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"callback")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#socket"},(0,r.kt)("inlineCode",{parentName:"a"},"<Socket>")))),(0,r.kt)("p",null,"Register a new handler for the given event."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("news", (data) => {\n  console.log(data);\n});\n// with several arguments\nsocket.on("news", (arg1, arg2, arg3) => {\n  // ...\n});\n// or with acknowledgement\nsocket.on("news", (data, callback) => {\n  callback(0);\n});\n')),(0,r.kt)("h4",{id:"socketonanycallback"},"socket.onAny(callback)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"callback")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Register a new catch-all listener."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"socket.onAny((event, ...args) => {\n  console.log(`got ${event}`);\n});\n")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},(0,r.kt)("a",{parentName:"p",href:"/docs/v4/emitting-events/#acknowledgements"},"Acknowledgements")," are not caught in the catch-all listener."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.emit("foo", (value) => {\n  // ...\n});\n\nsocket.onAnyOutgoing(() =>
1 {\n  // triggered when the event is sent\n});\n\nsocket.onAny(() => {\n  // not triggered when the acknowledgement is received\n});\n'))),(0,r.kt)("h4",{id:"socketonanyoutgoingcallback"},"socket.onAnyOutgoing(callback)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"callback")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Register a new catch-all listener for outgoing packets."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"socket.onAnyOutgoing((event, ...args) => {\n  console.log(`got ${event}`);\n});\n")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},(0,r.kt)("a",{parentName:"p",href:"/docs/v4/emitting-events/#acknowledgements"},"Acknowledgements")," are not caught in the catch-all listener."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-js"},'socket.on("foo", (value, callback) => {\n  callback("OK");\n});\n\nsocket.onAny(() => {\n  // triggered when the event is received\n});\n\nsocket.onAnyOutgoing(() =>
1 {\n  // not triggered when the acknowledgement is sent\n});\n'))),(0,r.kt)("h4",{id:"socketonceeventname-listener"},"socket.once(eventName, listener)"),(0,r.kt)("p",null,"Inherited from ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter")," (along with other methods not mentioned here). See the Node.js documentation for the ",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org/docs/latest/api/events.html"},"events")," module."),(0,r.kt)("h4",{id:"socketprependanycallback"},"socket.prependAny(callback)"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"callback")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Register a new catch-all listener. The listener is added to the beginning of the listeners array."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"socket.prependAny((event, ...args) => {\n  console.log(`got ${event}`);\n});\n")),(0,r.kt)("h4",{id:"socketprependanyoutgoingcallback"},"socket.prependAnyOutgoing(callback)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.5.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"callback")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Register a new catch-all listener for outgoing packets. The listener is added to the beginning of the listeners array."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"socket.prependAnyOutgoing((event, ...args) => {\n  console.log(`got ${event}`);\n});\n")),(0,r.kt)("h4",{id:"socketremovealllistenerseventname"},"socket.removeAllListeners(","[eventName]",")"),(0,r.kt)("p",null,"Inherited from ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter")," (along with other methods not mentioned here). See the Node.js documentation for the ",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org/docs/latest/api/events.html"},"events")," module."),(0,r.kt)("h4",{id:"socketremovelistenereventname-listener"},"socket.removeListener(eventName, listener)"),(0,r.kt)("p",null,"Inherited from ",(0,r.kt)("inlineCode",{parentName:"p"},"EventEmitter")," (along with other methods not mentioned here). See the Node.js documentation for the ",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org/docs/latest/api/events.html"},"events")," module."),(0,r.kt)("h4",{id:"socketsendargs"},"socket.send(","[...args][, ack]",")"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"args")," ",(0,r.kt)("inlineCode",{parentName:"li"},"<any[]>")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"ack")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#socket"},(0,r.kt)("inlineCode",{parentName:"a"},"Socket")))),(0,r.kt)("p",null,"Sends a ",(0,r.kt)("inlineCode",{parentName:"p"},"message")," event. See ",(0,r.kt)("a",{parentName:"p",href:"#socketemiteventname-args-ack"},"socket.emit(eventName[, ...args][, ack])"),"."),(0,r.kt)("h4",{id:"sockettimeoutvalue"},"socket.timeout(value)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.4.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"value")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("a",{parentName:"li",href:"#socket"},(0,r.kt)("inlineCode",{parentName:"a"},"<Socket>")))),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the callback will be called with an error when the\ngiven number of milliseconds have elapsed without an acknowledgement from the client:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"}
1,'socket.timeout(5000).emit("my-event", (err) => {\n  if (err) {\n    // the client did not acknowledge the event in the given delay\n  }\n});\n')),(0,r.kt)("h4",{id:"sockettoroom"},"socket.to(room)"),(0,r.kt)("details",{className:"changelog"},(0,r.kt)("summary",null,"History"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Version"),(0,r.kt)("th",{parentName:"tr",align:null},"Changes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v4.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Allow to pass an array of rooms.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Initial implementation."))))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"room")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#str
1ing_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string>"))," | ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<string[]>"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Returns")," ",(0,r.kt)("inlineCode",{parentName:"li"},"Socket")," for chaining")),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to clients that have joined the given ",(0,r.kt)("inlineCode",{parentName:"p"},"room")," (the socket itself being excluded)."),(0,r.kt)("p",null,"To emit to multiple rooms, you can call ",(0,r.kt)("inlineCode",{parentName:"p"},"to")," several times."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n\n  // to one room\n  socket.to("others").emit("an event", { some: "data" });\n\n  // to multiple rooms\n  socket.to("room1").to("room2").emit("hello");\n\n  // or with an array\n  socket.to(["room1", "room2"]).emit("hello");\n\n  // a private message to another socket\n  socket.to(/* another socket id */).emit("hey");\n\n  // WARNING: `socket.to(socket.id).emit()` will NOT work\n  // Please use `io.to(socket.id).emit()` instead.\n});\n')),(0,r.kt)("h4",{id:"socketusefn"},"socket.use(fn)"),(0,r.kt)("details",{className:"changelog"},(0,r.kt)("summary",null,"History"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Version"),(0,r.kt)("th",{parentName:"tr",align:null},"Changes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v3.0.5"),(0,r.kt)("td",{parentName:"tr",align:null},"Restoration of the first implementation.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v3.0.0"),(0,r.kt)("td",{parentName:"tr",align:null},"Removal in favor of ",(0,r.kt)("inlineCode",{parentName:"td"},"socket.onAny()"),".")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.7.2"),(0,r.kt)("td",{parentName:"tr",align:null},"The ",(0,r.kt)("inlineCode",{parentName:"td"},"error")," event is sent directly to the client.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"v1.6.0"),(0,r.kt)("td",{parentName:"tr",align:null},"First implementation."))))),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"fn")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Registers a middleware, which is a function that gets executed for every incoming ",(0,r.kt)("inlineCode",{parentName:"p"},"Packet")," and receives as parameter the packet and a function to optionally defer execution to the next registered middleware."),(0,r.kt)("p",null,"Errors passed to the middleware callback are then emitted as ",(0,r.kt)("inlineCode",{parentName:"p"},"error")," events on the server-side:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.use(([event, ...args], next) => {\n    if (isUnauthorized(event)) {\n      return next(new Error("unauthorized event"));\n    }\n    // do not forget to call next\n    next();\n  });\n\n  socket.on("error", (err) => {\n    if (err && err.message === "unauthorized event") {\n      socket.disconnect();\n    }\n  });\n});\n')),(0,r.kt)("h3",{id:"flags-1"},"Flags"),(0,r.kt)("h4",{id:"flag-broadcast"},"Flag: 'broadcast'"),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event data will only be ",(0,r.kt)("em",{parentName:"p"},"broadcast")," to every sockets but the sender."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.broadcast.emit("an event", { some: "data" }); // everyone gets it but the sender\n});\n')),(0,r.kt)("h4",{id:"flag-volatile-1"},"Flag: 'volatile'"),(0,r.kt)("p",null,"Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to receive messages (because of network slowness or other issues, or because they\u2019re connected through long polling and is in the middle of a request-response cycle)."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n  socket.volatile.emit("an event", { some: "data" }); // the client may or may not receive it\n});\n')),(0,r.kt)("h2",{id:"client"},"Client"),(0,r.kt)(o.Z,{alt:"Client in the class diagram for the server",sources:{light:(0,l.Z)("/images/server-class-diagram-client.png"),dark:(0,l.Z)("/images/server-class-diagram-client-dark.png")},mdxType:"ThemedImage"}),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"Client")," class represents an incoming transport (engine.io) connection. A ",(0,r.kt)("inlineCode",{parentName:"p"},"Client")," can be associated with many multiplexed ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket"),"s that belong to different ",(0,r.kt)("inlineCode",{parentName:"p"}
1,"Namespace"),"s."),(0,r.kt)("h3",{id:"attributes-3"},"Attributes"),(0,r.kt)("h4",{id:"clientconn"},"client.conn"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"<engine.Socket>"))),(0,r.kt)("p",null,"A reference to the underlying ",(0,r.kt)("inlineCode",{parentName:"p"},"engine.io")," ",(0,r.kt)("inlineCode",{parentName:"p"},"Socket")," connection."),(0,r.kt)("h4",{id:"clientrequest"},"client.request"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/api/http.html#class-httpincomingmessage"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.IncomingMessage>")))),(0,r.kt)("p",null,"A getter proxy that returns the reference to the ",(0,r.kt)("inlineCode",{parentName:"p"},"request")," that originated the engine.io connection. Useful for accessing request headers such as ",(0,r.kt)("inlineCode",{parentName:"p"},"Cookie")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"User-Agent"),"."),(0,r.kt)("h2",{id:"engine"},"Engine"),(0,r.kt)("p",null,"The Engine.IO server, which manages the WebSocket / HTTP long-polling connections. More information ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/how-it-works/"},"here"),"."),(0,r.kt)("p",null,"Its source code can be found here: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/socketio/engine.io"},"https://github.com/socketio/engine.io")),(0,r.kt)("h3",{id:"events-3"},"Events"),(0,r.kt)("h4",{id:"event-connection_error"},"Event: 'connection_error'"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.1.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"error")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error"},(0,r.kt)("inlineCode",{parentName:"a"},"<Error>")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'io.engine.on("connection_error", (err) => {\n  console.log(err.req);      // the request object\n  console.log(err.code);     // the error code, for example 1\n  console.log(err.message);  // the error message, for example "Session ID unknown"\n  console.log(err.context);  // some additional error context\n});\n')),(0,r.kt)("p",null,"This event will be emitted when a connection is abnormally closed. Here is the list of possible error codes:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:"center"},"Code"),(0,r.kt)("th",{parentName:"tr",align:"center"},"Message"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"center"},"0"),(0,r.kt)("td",{parentName:"tr",align:"center"},'"Transport unknown"')),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"center"},"1"),(0,r.kt)("td",{parentName:"tr",align:"center"},'"Session ID unknown"')),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"center"},"2"),(0,r.kt)("td",{parentName:"tr",align:"center"},'"Bad handshake method"')),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"center"},"3"),(0,r.kt)("td",{parentName:"tr",align:"center"},'"Bad request"')),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"center"},"4"),(0,r.kt)("td",{parentName:"tr",align:"center"},'"Forbidden"')),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"center"},"5"),(0,r.kt)("td",{parentName:"tr",align:"center"},'"Unsupported protocol version"')))),(0,r.kt)("h4",{id:"event-headers"},"Event: 'headers'"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.1.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"headers")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>"))," a hash of headers, indexed by header name"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"request")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/docs/latest/api/http.html#http_class_http_incomingmessage"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.IncomingMessage>"))," the incoming request")),(0,r.kt)("p",null,"This event will be emitted just before writing the response headers of ",(0,r.kt)("strong",{parentName:"p"},"each")," HTTP request of the session (including the WebSocket upgrade), allowing you to customize them."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { serialize, parse } from "cookie";\n\nio.engine.on("headers", (headers, request) => {\n  if (!request.headers.cookie) return;\n  const cookies = parse(request.headers.cookie);\n  if (!cookies.randomId) {\n    headers["set-cookie"] = serialize("randomId", "abc", { maxAge: 8
16400 });\n  }\n});\n')),(0,r.kt)("h4",{id:"event-initial_headers"},"Event: 'initial_headers'"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.1.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"headers")," ",(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"},(0,r.kt)("inlineCode",{parentName:"a"},"<Object>"))," a hash of headers, indexed by header name"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"request")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/docs/latest/api/http.html#http_class_http_incomingmessage"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.IncomingMessage>"))," the incoming request")),(0,r.kt)("p",null,"This event will be emitted just before writing the response headers of ",(0,r.kt)("strong",{parentName:"p"},"the first")," HTTP request of the session (the handshake), allowing you to customize them."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { serialize } from "cookie";\n\nio.engine.on("initial_headers", (headers, request) => {\n  headers["set-cookie"] = serialize("uid", "1234", { sameSite: "strict" });\n});\n')),(0,r.kt)("p",null,"If you need to perform some asynchronous operations, you will need to use the ",(0,r.kt)("a",{parentName:"p",href:"/docs/v4/server-options/#allowrequest"},(0,r.kt)("inlineCode",{parentName:"a"},"allowRequest"))," option:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { serialize } from "cookie";\n\nconst io = new Server(httpServer, {\n  allowRequest: async (req, callback) => {\n    const session = await fetchSession(req);\n    req.session = session;\n    callback(null, true);\n  }\n});\n\nio.engine.on("initial_headers", (headers, req) => {\n  if (req.session) {\n    headers["set-cookie"] = serialize("sid", req.session.id, { sameSite: "strict" });\n  }\n});\n')),(0,r.kt)("p",null,"See also:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/how-to/use-with-express-session"},"how to use with ",(0,r.kt)("inlineCode",{parentName:"a"},"express-session"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/how-to/deal-with-cookies"},"how to deal with cookies"))),(0,r.kt)("h3",{id:"attributes-4"},"Attributes"),(0,r.kt)("h4",{id:"engineclientscount"},"engine.clientsCount"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type"},(0,r.kt)("inlineCode",{parentName:"a"},"<number>")))),(0,r.kt)("p",null,"The number of currently connected clients."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const count = io.engine.clientsCount;\n// may or may not be similar to the count of Socket instances in the main namespace, depending on your usage\nconst count2 = io.of("/").sockets.size;\n')),(0,r.kt)("h3",{id:"methods-3"},"Methods"),(0,r.kt)("h4",{id:"enginegenerateid"},"engine.generateId"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"The function used to generate a new session ID. Defaults to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/faeldt/base64id"},"base64id"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const uuid = require("uuid");\n\nio.engine.generateId = () => {\n  return uuid.v4(); // must be unique across all Socket.IO servers\n}\n')),(0,r.kt)("h4",{id:"enginehandleupgraderequest-socket-head"},"engine.handleUpgrade(request, socket, head)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v1.0.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"request")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/docs/latest/api/http.html#http_class_http_incomingmessage"},(0,r.kt)("inlineCode",{parentName:"a"},"<http.IncomingMessage>"))," the incoming request"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"socket")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/docs/latest/api/stream.html#stream_class_stream_duplex"},(0,r.kt)("inlineCode",{parentName:"a"},"<stream.Duplex>"))," the network socket between the server and client"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"head")," ",(0,r.kt)("a",{parentName:"li",href:"https://nodejs.org/docs/latest/api/buffer.html#buffer_class_buffer"},(0,r.kt)("inlineCode",{parentName:"a"},"<Buffer>"))," the first packet of the upgraded stream (may be empty)")),(0,r.kt)("p",null,"This method can be used to inject an HTTP upgrade:"),(0,r.kt)("p",null,"Example with both a Socket.IO server and a plain WebSocket server:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import { createServer } from "http";\nimport { Server as WsServer } from "ws";\nimport { Server } from "socket.io";\n\nconst httpServer = createServer();\nconst wss = new WsServer({ noServer: true });\nconst io = new Server(httpServer);\n\nhttpServer.removeAllListeners("upgrade");\n\nhttpServer.on("upgrade", (req, socket, head) => {\n  if (req.url === "/") {\n    wss.handleUpgrade(req, socket, head, (ws) =>
1 {\n      wss.emit("connection", ws, req);\n    });\n  } else if (req.url.startsWith("/socket.io/")) {\n    io.engine.handleUpgrade(req, socket, head);\n  } else {\n    socket.destroy();\n  }\n});\n\nhttpServer.listen(3000);\n')),(0,r.kt)("h4",{id:"engineusemiddleware"},"engine.use(middleware)"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Added in v4.6.0")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"},(0,r.kt)("inlineCode",{parentName:"a"},"<Function>")))),(0,r.kt)("p",null,"Adds a new ",(0,r.kt)("a",{parentName:"p",href:"https://expressjs.com/en/guide/using-middleware.html"},"Express middleware"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"io.engine.use((req, res, next) => {\n  // do something\n\n  next();\n});\n")),(0,r.kt)("p",null,"The middlewares will be called for each incoming HTTP requests, including upgrade requests."),(0,r.kt)("p",null,"Example with ",(0,r.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/express-session"},(0,r.kt)("inlineCode",{parentName:"a"},"express-session")),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import session from "express-session";\n\nio.engine.use(session({\n  secret: "keyboard cat",\n  resave: false,\n  saveUninitialized: true,\n  cookie: { secure: true }\n}));\n')),(0,r.kt)("p",null,"Example with ",(0,r.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/helmet"},(0,r.kt)("inlineCode",{parentName:"a"},"helmet")),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'import helmet from "helmet";\n\nio.engine.use(helmet());\n')))}u.isMDXComponent=!0}}]);

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.