1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[2962],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});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 i(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 s(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):i(i({},t),e)),n},d=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(n),g=a,m=p["".concat(l,".").concat(g)]||p[g]||u[g]||r;return n?o.createElement(m,i(i({ref:t},d),{},{components:n})):o.createElement(m,i({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var c=2;c<r;c++)i[c]=n[c];return o.createElement.apply(null,i)}return o.createElement.apply(null,n)}g.displayName="MDXCreateElement"},8485:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var o=n(3117),a=(n(7294),n(3905));const r={title:"Migrating from 0.9",sidebar_position:1,slug:"/migrating-from-0-9/"},i=void 0,s={unversionedId:"categories/Migrations/migrating-from-0-9",id:"version-2.x/categories/Migrations/migrating-from-0-9",title:"Migrating from 0.9",description:"For most applications, the transition to 1.0 should be completely seamless and devoid of any hiccups. That said, we\u2019ve done some work to streamline some APIs, and we have changed some internals, so this is a recommended read for most existing users.",source:"@site/versioned_docs/version-2.x/categories/05-Migrations/migrating-from-0-9.md",sourceDirName:"categories/05-Migrations",slug:"/migrating-from-0-9/",permalink:"/docs/v2/migrating-from-0-9/",draft:!1,editUrl:"https://github.com/socketio/socket.io-website/edit/main/versioned_docs/version-2.x/categories/05-Migrations/migrating-from-0-9.md",tags:[],version:"2.x",lastUpdatedAt:1784117104,formattedLastUpdatedAt:"Jul 15, 2026",sidebarPosition:1,frontMatter:{title:"Migrating from 0.9",sidebar_position:1,slug:"/migrating-from-0-9/"},sidebar:"version-2.x/sidebar",previous:{title:"Internals overview",permalink:"/docs/v2/internals/"},next:{title:"FAQ",permalink:"/docs/v2/faq/"}},l={},c=[{value:"Authentication differences",id:"authentication-differences",level:2},{value:"Socket.io uses middleware now",id:"socketio-uses-middleware-now",level:3},{value:"\u2026 so its cleaner to do auth via middleware now",id:"-so-its-cleaner-to-do-auth-via-middleware-now",level:3},{value:"Namespace authorization?",id:"namespace-authorization",level:3},{value:"Log differences",id:"log-differences",level:2},{value:"Logging is now based on debug",id:"logging-is-now-based-on-debug",level:3},{value:"Shortcuts",id:"shortcuts",level:2},{value:"Broadcasting to all clients in default namespace",id:"broadcasting-to-all-clients-in-default-namespace",level:3},{value:"Starting the server",id:"starting-the-server",level:3},{value:"Configuration differences",id:"configuration-differences",level:2},{value:"io.set is gone",id:"ioset-is-gone",level:3},{value:"Setting resource path",id:"setting-resource-path",level:3},{value:"Parser / Protocol differences",id:"parser--protocol-differences",level:2},{value:"Difference 1 \u2013 packet encoding",id:"difference-1--packet-encoding",level:3},{value:"Difference 2 \u2013 packet decoding",id:"difference-2--packet-decoding",level:3}],d={toc:c},p="wrapper";
1function u(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"For most applications, the transition to 1.0 should be completely seamless and devoid of any hiccups. That said, we\u2019ve done some work to streamline some APIs, and we have changed some internals, so this is a recommended read for most existing users."),(0,a.kt)("h2",{id:"authentication-differences"},"Authentication differences"),(0,a.kt)("h3",{id:"socketio-uses-middleware-now"},"Socket.io uses middleware now"),(0,a.kt)("p",null,"You can give a Socket.io server arbitrary functions via ",(0,a.kt)("inlineCode",{parentName:"p"},"io.use()")," that are run when a socket is created. Check out this example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var srv = require('http').createServer();\nvar io = require('socket.io')(srv);\nvar run = 0;\nio.use(function(socket, next){\n run++; // 0 -> 1\n next();\n});\nio.use(function(socket, next) {\n run++; // 1 -> 2\n next();\n});\nvar socket = require('socket.io-client')();\nsocket.on('connect', function(){\n // run == 2 at this time\n});\n")),(0,a.kt)("h3",{id:"-so-its-cleaner-to-do-auth-via-middleware-now"},"\u2026 so its cleaner to do auth via middleware now"),(0,a.kt)("p",null,"The old ",(0,a.kt)("inlineCode",{parentName:"p"},"io.set()")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"io.get()")," methods are deprecated and only supported for backwards compatibility. Here is a translation of an old authorization example into middleware-style."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"io.set('authorization', function (handshakeData, callback) {\n // make sure the handshake data looks good\n callback(null, true); // error first, 'authorized' boolean second \n});\n")),(0,a.kt)("p",null,"vs."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"io.use(function(socket, next) {\n var handshakeData = socket.request;\n // make sure the handshake data looks good as before\n // if error do this:\n // next(new Error('not authorized'));\n // else just call next\n next();\n});\n")),(0,a.kt)("h3",{id:"namespace-authorization"},"Namespace authorization?"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"io.of('/namespace').use(function(socket, next) {\n var handshakeData = socket.request;\n next();\n});\n")),(0,a.kt)("h2",{id:"log-differences"},"Log differences"),(0,a.kt)("h3",{id:"logging-is-now-based-on-debug"},"Logging is now based on debug"),(0,a.kt)("p",null,"To print all debug logging, set the environment variable DEBUG to ",(0,a.kt)("em",{parentName:"p"},". ie: `DEBUG=")," node index.js`"),(0,a.kt)("p",null,"To print only socket.io related logging: ",(0,a.kt)("inlineCode",{parentName:"p"},"DEBUG=socket.io:* node index.js"),"."),(0,a.kt)("p",null,"To print logging only from the socket object: ",(0,a.kt)("inlineCode",{parentName:"p"},"DEBUG=socket.io:socket node index.js"),"."),(0,a.kt)("p",null,"This pattern should hopefully be making sense at this point. The names of the files in socket.io/lib are equivalent to their debug names."),(0,a.kt)("p",null,"Debug also works in the browser; logs are persisted to localstorage."),(0,a.kt)("p",null,"To use: open the developer console and type ",(0,a.kt)("inlineCode",{parentName:"p"},"localStorage.debug = 'socket.io:*'")," (or any debug level) and then refresh the page. Everything is logged until you run ",(0,a.kt)("inlineCode",{parentName:"p"},"localStorage.debug = ''")),(0,a.kt)("p",null,"See more at the debug documentation ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.org/package/debug"},"here"),"."),(0,a.kt)("h2",{id:"shortcuts"},"Shortcuts"),(0,a.kt)("p",null,"In general there are some new shortcuts for common things. The old versions should still work, but shortcuts are nice."),(0,a.kt)("h3",{id:"broadcasting-to-all-clients-in-default-namespace"},"Broadcasting to all clients in default namespace"),(0,a.kt)("p",null,"Previously:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"io.sockets.emit('eventname', 'eventdata');\n")),(0,a.kt)("p",null,"Now:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"io.emit('eventname', 'eventdata');\n")),(0,a.kt)("p",null,"Neat. Note that in both cases, these messages reach all clients connected to the default \u2018/\u2019 namespace, but not clients in other namespaces."),(0,a.kt)("h3",{id:"starting-the-server"},"Starting the server"),(0,a.kt)("p",null,"Previously:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var io = require('socket.io');\nvar socket = io.listen(80, { /* options */ });\n")),(0,a.kt)("p",null,"Now:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var io = require('socket.io');\nvar socket = io({ /* options */ });\n")),(0,a.kt)("h2",{id:"configuration-differences"},"Configuration differences"),(0,a.kt)("h3",{id:"ioset-is-gone"},"io.set is gone"),(0,a.kt)("p",null,"Instead do configuration in server initialization like this:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var socket = require('socket.io')({\n // options go here\n});\n")),(0,a.kt)("p",null,"Options like log-level are gone. ",(0,a.kt)("inlineCode",{parentName:"p"},"io.set('transports')"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"io.set('heartbeat interval')"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"io.set('heartbeat timeout'"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"io.set('resource')")," are still supported for backwards compatibility."),(0,a.kt)("h3",{id:"setting-resource-path"},"Setting resource path"),(0,a.kt)("p",null,"The previous ",(0,a.kt)("inlineCode",{parentName:"p"},"resource")," option is equivalent to the new ",(0,a.kt)("inlineCode",{parentName:"p"},"path")," option, but needs a ",(0,a.kt)("inlineCode",{parentName:"p"},"/")," in the beginning. For example, the following configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var socket = io.connect('localhost:3000', {\n 'resource': 'path/to/socket.io';\n});\n")),(0,a.kt)("p",null,"becomes:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var socket = io.connect('localhost:3000', {\n 'path': '/path/to/socket.io';\n});\n")),(0,a.kt)("h2",{id:"parser--protocol-differences"},"Parser / Protocol differences"),(0,a.kt)("p",null,"This is only relevant for updating things like socket.io implementations in other languages, custom socket.io clients, etc."),(0,a.kt)("h3",{id:"difference-1--packet-encoding"},"Difference 1 \u2013 packet encoding"),(0,a.kt)("p",null,"Parsing is now class based and asynchronous. Instead of returning a single encoded string, encode calls callback with an array of encodings as the only argument. Each encoding should be written to the transport in order. This is more flexible and makes binary data transport work. Here\u2019s an example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var encoding = parser.encode(packet);\nconsole.log(encoding); // fully encoded packet`\n")),(0,a.kt)("p",null,"vs."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var encoder = new parser.Encoder();\nencoder.encode(packet, function(encodings) {\n for (var i = 0; i < encodings.length;
1 i++) {\n console.log(encodings[i]); // encoded parts of the packet\n }\n});\n")),(0,a.kt)("h3",{id:"difference-2--packet-decoding"},"Difference 2 \u2013 packet decoding"),(0,a.kt)("p",null,"Decoding takes things a step further and is event-based. This is done because some objects (binary-containing) are both encoded and decoded in multiple parts. This example should help:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var packet = parser.decode(decoding);\nconsole.log(packet); // formed socket.io packet to handle\n")),(0,a.kt)("p",null,"vs."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"var decoder = new parser.Decoder();\ndecoder.on('decoded', function(packet) {\n console.log(packet); // formed socket.io packet to handle\n});\ndecoder.add(encodings[0]); // say encodings is array of two encodings received from transport\ndecoder.add(encodings[1]); // after adding the last element, 'decoded' is emitted from decoder\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.