1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[1032],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(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,o,a=function(e,t){if(null==e)return{};var n,o,a={},r=Object.keys(e);for(o=0;o<r.length;o++)n=r[o],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o<r.length;o++)n=r[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=o.createContext({}),c=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},m=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",k={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),p=c(n),d=a,u=p["".concat(l,".").concat(d)]||p[d]||k[d]||r;return n?o.createElement(u,s(s({ref:t},m),{},{components:n})):o.createElement(u,s({ref:t},m))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,s=new Array(r);s[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:a,s[1]=i;for(var c=2;c<r;c++)s[c]=n[c];return o.createElement.apply(null,s)}return o.createElement.apply(null,n)}d.displayName="MDXCreateElement"},7286:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>k,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var o=n(3117),a=(n(7294),n(3905));const r={title:"The Server instance",sidebar_position:3,slug:"/server-instance/"},s=void 0,i={unversionedId:"categories/Server/server-instance",id:"categories/Server/server-instance",title:"The Server instance",description:"The Server instance (often called io in the code examples) has a few attributes that may be of use in your application.",source:"@site/docs/categories/02-Server/server-instance.md",sourceDirName:"categories/02-Server",slug:"/server-instance/",permalink:"/docs/v4/server-instance/",draft:!1,editUrl:"https://github.com/socketio/socket.io-website/edit/main/docs/categories/02-Server/server-instance.md",tags:[],version:"current",lastUpdatedAt:1784117104,formattedLastUpdatedAt:"Jul 15, 2026",sidebarPosition:3,frontMatter:{title:"The Server instance",sidebar_position:3,slug:"/server-instance/"},sidebar:"sidebar",previous:{title:"Initialization",permalink:"/docs/v4/server-initialization/"},next:{title:"The Socket instance",permalink:"/docs/v4/server-socket-instance/"}},l={},c=[{value:"Server#engine",id:"serverengine",level:2},{value:"Utility methods",id:"utility-methods",level:2},{value:"<code>socketsJoin</code>",id:"socketsjoin",level:3},{value:"<code>socketsLeave</code>",id:"socketsleave",level:3},{value:"<code>disconnectSockets</code>",id:"disconnectsockets",level:3},{value:"<code>fetchSockets</code>",id:"fetchsockets",level:3},{value:"<code>serverSideEmit</code>",id:"serversideemit",level:3},{value:"Events",id:"events",level:2},{value:"<code>connection</code>",id:"connection",level:3},{value:"Complete API",id:"complete-api",level:2}],m={toc:c},p="wrapper";function k(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The Server instance (often called ",(0,a.kt)("inlineCode",{parentName:"p"},"io")," in the code examples) has a few attributes that may be of use in your application."),(0,a.kt)("p",null,"It also inherits all the methods of the ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/namespaces/#main-namespace"},"main namespace"),", like ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/server-api/#namespaceusefn"},(0,a.kt)("inlineCode",{parentName:"a"},"namespace.use()"))," (see ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/middlewares/"},"here"),") or ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/server-api/#namespaceallsockets"},(0,a.kt)("inlineCode",{parentName:"a"},"namespace.allSockets()")),"."),(0,a.kt)("h2",{id:"serverengine"},"Server#engine"),(0,a.kt)("p",null,"A reference to the underlying Engine.IO server."),(0,a.kt)("p",null,"It can be used to fetch the number of currently connected clients:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("p",null,"Or to generate a custom session ID (the ",(0,a.kt)("inlineCode",{parentName:"p"},"sid")," query parameter):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'const uuid = require("uuid");\n\nio.engine.generateId = (req) => {\n return uuid.v4(); // must be unique across all Socket.IO servers\n}\n')),(0,a.kt)("p",null,"As of ",(0,a.kt)("inlineCode",{parentName:"p"},"[email protected]"),", the Engine.IO server emits three special events:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"initial_headers"),": will be emitted just before writing the response headers of the first HTTP request of the session (the handshake), allowing you to customize them.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.engine.on("initial_headers", (headers, req) => {\n headers["test"] = "123";
1\n headers["set-cookie"] = "mycookie=456";\n});\n')),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"headers"),": will be emitted just before writing the response headers of each HTTP request of the session (including the WebSocket upgrade), allowing you to customize them.")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.engine.on("headers", (headers, req) => {\n headers["test"] = "789";\n});\n')),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"connection_error"),": will be emitted when a connection is abnormally closed")),(0,a.kt)("pre",null,(0,a.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,a.kt)("p",null,"Here is the list of possible error codes:"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:"center"},"Code"),(0,a.kt)("th",{parentName:"tr",align:"center"},"Message"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"center"},"0"),(0,a.kt)("td",{parentName:"tr",align:"center"},'"Transport unknown"')),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"center"},"1"),(0,a.kt)("td",{parentName:"tr",align:"center"},'"Session ID unknown"')),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"center"},"2"),(0,a.kt)("td",{parentName:"tr",align:"center"},'"Bad handshake method"')),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"center"},"3"),(0,a.kt)("td",{parentName:"tr",align:"center"},'"Bad request"')),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"center"},"4"),(0,a.kt)("td",{parentName:"tr",align:"center"},'"Forbidden"')),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"center"},"5"),(0,a.kt)("td",{parentName:"tr",align:"center"},'"Unsupported protocol version"')))),(0,a.kt)("h2",{id:"utility-methods"},"Utility methods"),(0,a.kt)("p",null,"Some utility methods were added in Socket.IO v4.0.0 to manage the Socket instances and their rooms:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#socketsjoin"},(0,a.kt)("inlineCode",{parentName:"a"},"socketsJoin")),": makes the matching socket instances join the specified rooms"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#socketsleave"},(0,a.kt)("inlineCode",{parentName:"a"},"socketsLeave")),": makes the matching socket instances leave the specified rooms"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#disconnectsockets"},(0,a.kt)("inlineCode",{parentName:"a"},"disconnectSockets")),": makes the matching socket instances disconnect"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#fetchsockets"},(0,a.kt)("inlineCode",{parentName:"a"},"fetchSockets")),": returns the matching socket instances")),(0,a.kt)("p",null,"The ",(0,a.kt)("a",{parentName:"p",href:"#serversideemit"},(0,a.kt)("inlineCode",{parentName:"a"},"serverSideEmit"))," method was added in Socket.IO v4.1.0."),(0,a.kt)("p",null,"Those methods share the same semantics as broadcasting, and the same filters apply:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/admin").in("room1").except("room2").local.disconnectSockets();\n')),(0,a.kt)("p",null,'Which makes all Socket instances of the "admin" namespace'),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'in the "room1" room (',(0,a.kt)("inlineCode",{parentName:"li"},'in("room1")')," or ",(0,a.kt)("inlineCode",{parentName:"li"},'to("room1")'),")"),(0,a.kt)("li",{parentName:"ul"},'except the ones in "room2" (',(0,a.kt)("inlineCode",{parentName:"li"},'except("room2")'),")"),(0,a.kt)("li",{parentName:"ul"},"and only on the current Socket.IO server (",(0,a.kt)("inlineCode",{parentName:"li"},"local"),")")),(0,a.kt)("p",null,"disconnect."),(0,a.kt)("p",null,"Please note that they are also compatible with the Redis adapter (starting with ",(0,a.kt)("inlineCode",{parentName:"p"},"[email protected]"),"), which means that they will work across Socket.IO servers."),(0,a.kt)("h3",{id:"socketsjoin"},(0,a.kt)("inlineCode",{parentName:"h3"},"socketsJoin")),(0,a.kt)("p",null,"This method makes the matching Socket instances join the specified rooms:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("h3",{id:"socketsleave"},(0,a.kt)("inlineCode",{parentName:"h3"},"socketsLeave")),(0,a.kt)("p",null,"This method makes the matching Socket instances leave the specified rooms:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("h3",{id:"disconnectsockets"},(0,a.kt)("inlineCode",{parentName:"h3"},"disconnectSockets")),(0,a.kt)("p",null,"This method makes the matching Socket instances disconnect:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("h3",{id:"fetchsockets"},(0,a.kt)("inlineCode",{parentName:"h3"},"fetchSockets")),(0,a.kt)("p",null,"This method returns the matching Socket instances:"),(0,a.kt)("pre",null,(0,a.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\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,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"sockets")," variable in the example above is an array of objects exposing a subset of the usual Socket class:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"data")," attribute is an arbitrary object that can be used to share information between Socket.IO servers:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("h3",{id:"serversideemit"},(0,a.kt)("inlineCode",{parentName:"h3"},"serverSideEmit")),(0,a.kt)("p",null,"This method allows to emit events to the other Socket.IO servers of the cluster, in a ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/using-multiple-nodes/"},"multi-server setup"),"."),(0,a.kt)("p",null,"Syntax:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.serverSideEmit("hello", "world");\n')),(0,a.kt)("p",null,"And on the receiving side:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.on("hello", (arg1) => {\n console.log(arg1); // prints "world"\n});\n')),(0,a.kt)("p",null,"Acknowledgements are supported too:"),(0,a.kt)("pre",null,(0,a.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,a.kt)("p",null,"Notes:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"the ",(0,a.kt)("inlineCode",{parentName:"p"},"connection"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"connect")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"new_namespace")," strings are reserved and cannot be used in your application.")),(0,a.kt)("li",{parentName:"ul"},(0,a.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,a.kt)("inlineCode",{parentName:"p"},"JSON.stringify"),"-ed)"))),(0,a.kt)("p",null,"Example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.serverSideEmit("hello", "world", 1, "2", { 3: "4" });\n')),(0,a.kt)("ul",null,(0,a.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,a.kt)("pre",null,(0,a.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,a.kt)("h2",{id:"events"},"Events"),(0,a.kt)("p",null,"The Server instance emits one single event (well, technically two, but ",(0,a.kt)("inlineCode",{parentName:"p"},"connect")," is an alias for ",(0,a.kt)("inlineCode",{parentName:"p"},"connection"),"):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#connection"},(0,a.kt)("inlineCode",{parentName:"a"},"connection")))),(0,a.kt)("h3",{id:"connection"},(0,a.kt)("inlineCode",{parentName:"h3"},"connection")),(0,a.kt)("p",null,"This event is fired upon a new connection. The first argument is a ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/server-socket-instance/"},"Socket instance"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {\n // ...\n});\n')),(0,a.kt)("h2",{id:"complete-api"},"Complete API"),(0,a.kt)("p",null,"The complete API exposed by the Server instance can be found ",(0,a.kt)("a",{parentName:"p",href:"/docs/v4/server-api/#server"},"here"),"."))}k.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.