PageSourceSearch

https://socket.io/assets/js/b2f554cd.eda7475c.js

js socket.io collected 2026-09-24 07:24:09 UTC 179,047 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/bun-engine/","metadata":{"permalink":"/blog/bun-engine/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2025-08-22-bun-engine.md","source":"@site/blog/2025-08-22-bun-engine.md","title":"Bun engine","description":"Hello everyone!","date":"2025-08-22T00:00:00.000Z","formattedDate":"August 22, 2025","tags":[],"readingTime":2.045,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Bun engine","slug":"/bun-engine/","authors":["darrachequesne"]},"nextItem":{"title":"npm package provenance","permalink":"/blog/npm-package-provenance/"}},"content":"Hello everyone!\\n\\nWe are happy to announce that we now provide a low-level engine for Bun.\\n\\n\x3c!--truncate--\x3e\\n\\n:::note for newcomers\\n\\n**Socket.IO** is a JavaScript library that enables real-time, bidirectional, and event-based communication between a client and a server. It is commonly used for building applications that require low-latency updates, such as chat applications, collaborative tools, or multiplayer games.\\n\\nTo achieve this, it automatically selects the best available low-level transport between [WebTransport](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API), [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) and HTTP long-polling, based on the capabilities of the client platform and the network.\\n\\n**Bun** is a fast all-in-one JavaScript runtime developed as a modern alternative to Node.js and Deno. It is designed to offer high performance, better developer experience, and compatibility with existing JavaScript/TypeScript projects.\\n\\nReference: https://bun.sh/\\n\\n:::\\n\\nBun could already be used without any modification:\\n\\n```js\\nimport { Server } from \\"socket.io\\";\\n\\nconst io = new Server({ /* options */ });\\n\\nio.on(\\"connection\\", (socket) => {\\n  // ...\\n});\\n\\nio.listen(3000);\\n```\\n\\nHowever, this relied on Bun\'s polyfill for the Node.js HTTP server.\\n\\nSo, in order to fully benefit from the performance of Bun\'s native HTTP server, we have created a dedicated engine:\\n\\n```js\\nimport { Server as Engine } from \\"@socket.io/bun-engine\\";\\nimport { Server } from \\"socket.io\\";\\n\\nconst io = new Server();\\n\\nconst engine = new Engine({\\n  path: \\"/socket.io/\\",\\n});\\n\\nio.bind(engine);\\n\\nio.on(\\"connection\\", (socket) => {\\n  // ...\\n});\\n\\nexport default {\\n  port: 3000,\\n  idleTimeout: 30, // must be greater than the \\"pingInterval\\" option of the engine, which defaults to 25 seconds\\n\\n  ...engine.handler(),\\n};\\n```\\n\\nWhich means that you can now take advantage of the speed and scalability of Bun, with the same high-level API offered by Socket.IO (and its existing adapters, when scaling to multiple servers).\\n\\nThe source code of this engine can be found here: https://github.com/socketio/bun-engine\\n\\n:::tip\\n\\nThis new engine can also be used in conjunction with Hono:\\n\\n```js\\nimport { Server } from \\"socket.io\\";\\nimport { Server as Engine } from \\"@socket.io/bun-engine\\";\\nimport { Hono } from \\"hono\\";\\n\\nconst io = new Server();\\nconst engine = new Engine();\\n\\nio.bind(engine);\\n\\nio.on(\\"connection\\", (socket) => {\\n  // ...\\n});\\n\\nconst app = new Hono();\\n\\nconst { websocket } = engine.handler();\\n\\nexport default {\\n  port: 3000,\\n  idleTimeout: 30, // must be greater than the \\"pingInterval\\" option of the engine, which defaults to 25 seconds\\n\\n  fetch(req, server) {\\n    const url = new URL(req.url);\\n\\n    if (url.pathname === \\"/socket.io/\\") {\\n      return engine.handleRequest(req, server);\\n    } else {\\n      return app.fetch(req, server);\\n    }\\n  },\\n\\n  websocket\\n}\\n```\\n\\nReference: https://hono.dev/docs/\\n\\n:::\\n\\nHave a great day!"},{"id":"/npm-package-provenance/","metadata":{"permalink":"/blog/npm-package-provenance/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2024-07-25-npm-provenance-statements.md","source":"@site/blog/2024-07-25-npm-provenance-statements.md","title":"npm package provenance","description":"Hello everyone!","date":"2024-0
17-25T00:00:00.000Z","formattedDate":"July 25, 2024","tags":[],"readingTime":1.915,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"npm package provenance","slug":"/npm-package-provenance/","authors":["darrachequesne"]},"prevItem":{"title":"Bun engine","permalink":"/blog/bun-engine/"},"nextItem":{"title":"Socket.IO monorepo","permalink":"/blog/monorepo/"}},"content":"Hello everyone!\\n\\nWe are happy to announce that Socket.IO packages will now be published with a provenance statement.\\n\\n\x3c!--truncate--\x3e\\n\\n:::tip\\n\\nPackage provenance is a npm feature which was introduced last year to increase trust in the npm supply chain.\\n\\nThe idea is that the package is published and signed from a trusted CI/CD platform (such as GitHub Actions), so the code that ends up in the registry cannot be tampered with.\\n\\nMore info: https://github.blog/security/supply-chain-security/introducing-npm-package-provenance/\\n\\n:::\\n\\nStarting today, new Socket.IO versions will be published directly from GitHub Actions and no longer from a maintainer machine.\\n\\nThe publication workflow can be found here: [`publish.yml`](https://github.com/socketio/socket.io/blob/main/.github/workflows/publish.yml)\\n\\n## Notes\\n\\nThere are a few notable differences from the [reference workflow](https://docs.npmjs.com/generating-provenance-statements):\\n\\n### Workflow trigger\\n\\nThe workflow is triggered when pushing a tag to GitHub:\\n\\n```yml\\non:\\n  push:\\n    tags:\\n      - \'**@*\'\\n```\\n\\nThe expected format is `<package>@<version>`, for example:\\n\\n- `[email protected]`\\n- `@socket.io/[email protected]` (hence the `**` to match the `/` char)\\n\\nThe `<package>` part is then used to select the right workspace (since we are using [a monorepo](/blog/monorepo/)):\\n\\n```yml\\njobs:\\n  publish:\\n    steps:\\n      # [...]\\n\\n      - name: Publish package\\n        run: npm publish --workspace=${GITHUB_REF_NAME%@*} --provenance --access public\\n        env:\\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\\n```\\n\\nReference: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions\\n\\n### Compilation step\\n\\nA TypeScript compilation step is necessary, since some packages depend on the types of other packages:\\n\\n```yml\\njobs:\\n  publish:\\n    steps:\\n      # [...]\\n\\n      - name: Compile each package\\n        run: npm run compile --workspaces --if-present\\n\\n      - name: Publish package\\n      # [...]\\n```\\n\\n## First verified version\\n\\nThe latest version of the `engine.io-parser` package has been released this way.\\n\\nOn the [npmjs.com](https://www.npmjs.com/package/engine.io-parser) website, you can find:\\n\\n- the details of the build, at the bottom of the page:\\n\\n![Provenance details on www.npmjs.com](/images/blog/npm-package-provenance/provenance-details.png)\\n\\n- a checked badge, in the \\"Versions\\" tab\\n\\n![Provenance badge on www.npmjs.com](/images/blog/npm-package-provenance/provenance-badge.png)\\n\\nYou can also verify the attestations of your dependencies:\\n\\n```bash\\n$ npm i socket.io\\n\\nadded 22 packages, and audited 23 packages in 853ms\\n\\nfound 0 vulnerabilities\\n\\n$ npm audit signatures\\n\\naudited 22 packages in 1s\\n\\n22 packages have verified registry signatures\\n\\n1 package has a verified attestation # <-- it\'s a good start!\\n```\\n\\n## Conclusion\\n\\nThis is a big step forward in increasing trust in the JS ecosystem, congratulations to the npm team!\\n\\nSome big names have already joined the club:\\n\\n- [axios](https://www.npmjs.com/package/axios)\\n- [next](https://www.npmjs.com/package/next)\\n- [vite](https://www.npmjs.com/package/vite)\\n\\nThat\'s all folks, thanks for reading!"},{"id":"/monorepo/","metadata":{"permalink":"/blog/monorepo/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2024-07-12-monorepo.md","source":"@site/blog/2024-07-12-monorepo.md","title":"Socket.IO monorepo","de
1scription":"Hello everyone!","date":"2024-07-12T00:00:00.000Z","formattedDate":"July 12, 2024","tags":[],"readingTime":2.42,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO monorepo","slug":"/monorepo/","authors":["darrachequesne"]},"prevItem":{"title":"npm package provenance","permalink":"/blog/npm-package-provenance/"},"nextItem":{"title":"Three new adapters","permalink":"/blog/three-new-adapters/"}},"content":"Hello everyone!\\n\\nWe are happy to announce that the Socket.IO codebase has been merged into a monorepo.\\n\\n\x3c!--truncate--\x3e\\n\\n:::note\\n\\nA monorepo is a single repository containing multiple distinct projects, with well-defined relationships.\\n\\nMore info [here](https://monorepo.tools)\\n\\n:::\\n\\n## Modular architecture\\n\\nAs part of the work towards [v1.0](/blog/introducing-socket-io-1-0/) ten years ago (!), the Socket.IO codebase was split into several packages, each with its own responsibility:\\n\\n![Diagram of the package inter-dependencies](/images/blog/monorepo/packages.png)\\n\\nAt the time, tools like [`lerna`](https://lerna.js.org/) or [pnpm workspaces](https://pnpm.io/workspaces) that make it easier to develop and publish multiple JavaScript packages from the same repository did not exist yet, so the codebase was split into multiple GitHub repositories:\\n\\n- https://github.com/socketio/socket.io\\n- https://github.com/socketio/socket.io-client\\n- https://github.com/socketio/socket.io-parser\\n- ...\\n\\nHowever, this structure has several downsides:\\n\\n- it\'s harder for newcomers to dig into the codebase and understand what\'s going on under the hood\\n- a change that affects multiple repositories is more difficult to test\\n- mundane tasks like configuring CI or updating development dependencies must be replicated across all repositories\\n\\
1nThat\'s why we have made the decision to merge all repositories into [a single one](https://github.com/socketio/socket.io). The source codes for the different packages are now located in the `packages/` directory:\\n\\n```\\npackages/\\n\u251c\u2500\u2500 engine.io\\n\u251c\u2500\u2500 engine.io-client\\n\u251c\u2500\u2500 engine.io-parser\\n\u251c\u2500\u2500 socket.io\\n\u251c\u2500\u2500 socket.io-adapter\\n\u251c\u2500\u2500 socket.io-client\\n\u2514\u2500\u2500 socket.io-parser\\n```\\n\\n## Workspaces\\n\\nTo manage the packages, we use [npm workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces) which were introduced in npm v7 (bundled with Node.js v15). The `package.json` file at the root of the repository lists all packages and their development dependencies:\\n\\n```json title=\\"package.json\\"\\n{\\n  \\"private\\": true,\\n  \\"workspaces\\": [\\n    \\"packages/engine.io-parser\\",\\n    \\"packages/engine.io\\",\\n    \\"packages/engine.io-client\\",\\n    \\"packages/socket.io-adapter\\",\\n    \\"packages/socket.io-parser\\",\\n    \\"packages/socket.io-client\\",\\n    \\"packages/socket.io\\"\\n  ],\\n  \\"devDependencies\\": {\\n    // [...]\\n  }\\n}\\n```\\n\\nAfter cloning the repository, running `npm install` will fetch all necessary dependencies and create the links between the packages:\\n\\n```bash\\n$ npm ls\\nsocket.io@ /git/socket.io\\n\u2514\u2500\u252c [email protected] -> ./packages/socket.io\\n  \u251c\u2500\u2500 [email protected]\\n  \u251c\u2500\u2500 [email protected]\\n  \u251c\u2500\u2500 [email protected]\\n  \u251c\u2500\u2500 [email protected]\\n# highlight-next-line\\n  \u251c\u2500\u2500 [email protected] -> ./packages/engine.io\\n# highlight-next-line\\n  \u251c\u2500\u252c [email protected] -> ./packages/socket.io-adapter\\n  \u2502 \u251c\u2500\u2500 [email protected] deduped\\n  \u2502 \u2514\u2500\u2500 [email protected] overridden\\n# highlight-next-line\\n  \u2514\u2500\u252c [email protected] -> ./packages/socket.io-parser\\n    \u251c\u2500\u2500 @socket.io/[email protected] -> ./packages/socket.io-component-emitter\\n    \u2514\u2500\u2500 [email protected] deduped\\n```\\n\\nAnd finally, running `npm test --workspaces` (or `npm test -ws`) will run the tests on all workspaces, ensuring that any change is properly tested over the whole codebase.\\n\\n:::tip\\n\\nOur [contributing guide](https://github.com/socketio/socket.io/blob/main/CONTRIBUTING.md) has been updated accordingly.\\n\\n:::\\n\\n## Git history\\n\\nObviously, losing 10 years of git history from the other repositories was not an option. The repositories have thus been merged with the `--allow-unrelated-histories` option, in order to include their history in the monorepo:\\n\\n![Schema of the preserved git history](/images/blog/monorepo/git-history.png)\\n\\nReference: https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---allow-unrelated-histories\\n\\
1n## GitHub issues\\n\\nSimilarly, it was not conceivable to lose the list of open GitHub issues across all repositories, since it is our most valuable source of user feedback, so they have been moved to the main repository: https://github.com/socketio/socket.io/issues\\n\\nHopefully, this change should make it easier for anyone to contribute to the project in the future.\\n\\nThat\'s all folks, thanks for reading!"},{"id":"/three-new-adapters/","metadata":{"permalink":"/blog/three-new-adapters/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2024-03-29-new-adapters.md","source":"@site/blog/2024-03-29-new-adapters.md","title":"Three new adapters","description":"Hello everyone!","date":"2024-03-29T00:00:00.000Z","formattedDate":"March 29, 2024","tags":[],"readingTime":0.17,"hasTruncateMarker":false,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Three new adapters","slug":"/three-new-adapters/","authors":["darrachequesne"]},"prevItem":{"title":"Socket.IO monorepo","permalink":"/blog/monorepo/"},"nextItem":{"title":"Chat platform","permalink":"/blog/chat-platform/"}},"content":"Hello everyone!\\n\\nI\'m happy to announce that we provide 3 new official adapters:\\n\\n- the [Google Cloud Pub/Sub adapter](/docs/v4/gcp-pubsub-adapter/)\\n- the [AWS SQS adapter](/docs/v4/aws-sqs-adapter/)\\n- the [Azure Service Bus adapter](/docs/v4/azure-service-bus-adapter/)\\n\\nAny feedback is welcome!"},{"id":"/chat-platform/","metadata":{"permalink":"/blog/chat-platform/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2024-01-12-chat-platform.md","source":"@site/blog/2024-01-12-chat-platform.md","title":"Chat platform","description":"Hello everyone!","date":"2024-01-12T00:00:00.000Z","formattedDate":"January 12, 2024","tags":[],"readingTime":1.065,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Chat platform","slug":"/chat-platform/","authors":["darrachequesne"]},"prevItem":{"title":"Three new adapters","permalink":"/blog/three-new-adapters/"},"nextItem":{"title":"Socket.IO on Azure","permalink":"/blog/socket-io-on-azure-preview/"}},"content":"Hello everyone!\\n\\nA new sample project is available: the **Chat platform**.\\n\\nThe source code can be found [here](https://github.com/socketio/socket.io-chat-platform).\\n\\n\x3c!--truncate--\x3e\\n\\n:::note for newcomers\\n\\nSocket.IO is a library that enables low-latency, bidirectional and event-based communication between a client and a server.\\n\\nTo achieve this, it automatically selects the best available low-level transport between [WebTransport](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API), [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) and HTTP long-polling, based on the capabilities of the client platform and the network.\\n\\n:::\\n\\n## Goal\\n\\nThe goal of this project is to provide a full-blown project based on Socket.IO with:\\n\\n- authentication/user registration\\n- public and private messaging\\n- proper reconnection management\\n- presence management\\n\\nThe source code is provided with a permissive MIT license, so that you can use it/extend it to your will.\\n\\n## How to use\\n\\nCheck out the code [here](https://github.com/socketio/socket.io-chat-platform) and follow the instructions in the README.\\n\\n## Features\\n\\n### Channel-based messages\\n\\n![Screenshot of a public channel](/images/channel_based_messages.png)\\n\\n### Private messages\\n\\n![Screenshot of a private channel](/images/private_messages.png)\\n\\n## Tools\\n\\n### Server\\n\\nThe server is written in plain JavaScript, with the [`express`](https://expressjs.com/), `express-session` and [`passport`](https://www.passportjs.org/) packages. The database is [PostgreSQL](https://www.postgresql.org/).\\n\\n### Client\\n\\nThe client is a [Vue.js](https://vuejs.org/) single-page application, with the [`vue-router`](https://router.vuejs.org/) and [`pinia`](https://pinia.vuejs.org/) packages. It uses [Bootstrap v5](https://getbootstrap.com/) for the styles.\\n\\n## Roadmap\\n\\n- React client ([link](https://github.com/socketio/socket.io-chat-platform/issues/1))\\n- MongoDB server ([link](https://github.com/socketio/socket.io-chat-platform/issues/2))\\n\\nAny additional suggestion is wel
1come!"},{"id":"/socket-io-on-azure-preview/","metadata":{"permalink":"/blog/socket-io-on-azure-preview/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2023-08-23-socketio-on-azure.md","source":"@site/blog/2023-08-23-socketio-on-azure.md","title":"Socket.IO on Azure","description":"- Overview of Socket.IO support on Azure","date":"2023-08-23T00:00:00.000Z","formattedDate":"August 23, 2023","tags":[],"readingTime":2.625,"hasTruncateMarker":true,"authors":[{"name":"Kevin Guo","title":"Product Manager at Microsoft | Support for Socket.IO on Azure","url":"https://github.com/kevinguo-ed","imageURL":"https://github.com/kevinguo-ed.png","key":"kevinguo-ed"}],"frontMatter":{"title":"Socket.IO on Azure","slug":"/socket-io-on-azure-preview/","authors":["kevinguo-ed"]},"prevItem":{"title":"Chat platform","permalink":"/blog/chat-platform/"},"nextItem":{"title":"Redis Streams adapter","permalink":"/blog/socket-io-redis-streams-adapter/"}},"content":"- [Overview of Socket.IO support on Azure](https://learn.microsoft.com/azure/azure-web-pubsub/socketio-overview)\\n- [Quickstarts of hosting a Socket.IO app on Azure](https://learn.microsoft.com/azure/azure-web-pubsub/socketio-quickstart)\\n\\nHello developers, \\n\\nSince we put up an invitation to participate in a user study, we collected **hundreds of responses** and had the chance to speak in depth with several Socket.IO users. Thank you for your interest in the user study and helping us understand your experience. \\n\\nIn this post, I am going to share with you some notable learnings from the study. It\u2019s our hope that such sharing can shed light on how we can build a stronger community as Socket.IO users, contributors, and cloud providers. \\n\\n\x3c!--truncate--\x3e\\n\\n## Socket.IO is used in a wide range of app scenarios \\nWe were pleasantly surprised by the variety of applications built using Socket.IO. Although a fair number of users reported building chat apps using Socket.IO, many shared that they use Socket.IO for identity management to limit the number of active browser tabs, for robotics to control the movement of mobile robots, for multi-player mobile games and for collaborative apps where users can track work items in real-time.\\n\\n## Overwhelmingly, users enjoy the \u201cintuitive APIs\u201d\\nUsers seem to have exhausted the synonyms for \u201cintuitive\u201d in their responses. Once users have gone over the initial learning curve, it doesn\u2019t take long before they can get productive with Socket.IO\u2019s APIs, which are described as \u201csimple\u201d, \u201ceasy\u201d and \u201cplain\u201d. Plains APIs are definitely a praise in this case.\\n\\n## Some users seem to have doubts about Socket.IO\u2019s viability for large projects\\nUsers new to Socket.IO seem to have the impression that Socket.IO is for small-scale and toy projects and it would be necessary to find alternatives when an app needs to scale. I am happy to report that impression doesn\u2019t reflect the reality; a few Socket.IO users shared that their apps handled 10s of thousand concurrent connections well, powered by running multiple Socket.IO instances behind a load balancer.  \\n\\n## Scaling out a Socket.IO is where developers report the most pain\\nScaling out a Socket.IO app requires a multi-server setup. Essentially, client connections are spread across several Socket.IO server instances. To emit an event to clients connected with different server instances, there needs to be a component to coordinate the message passing. While simple in broad-stroke description, implementation is not particularly straight-forward or familiar to most users. Deploying and maintaining a separate adapter component add additional complexity to the task. \\n\\nThis is an area where we studied the most and thought we could bring the most value to developers. I am happy to share with you that with the input from the open-source community, we brought support for Socket.IO on Azure. With this support, Azure hosts and manages client connections;
1 in other words, developers don\u2019t need an \u201cadapter\u201d component. \\n\\nWhat\u2019s more important is that server and client apps continue using the **same and familiar Socket.IO APIs**. With only a few lines of code, you can get any socket.io apps running locally to Azure. You can learn more about the support and try it out for free by following the links below.\\n\\n- [Overview of Socket.IO support on Azure](https://learn.microsoft.com/azure/azure-web-pubsub/socketio-overview)\\n- [Quickstarts of hosting a Socket.IO app on Azure](https://learn.microsoft.com/azure/azure-web-pubsub/socketio-quickstart)"},{"id":"/socket-io-redis-streams-adapter/","metadata":{"permalink":"/blog/socket-io-redis-streams-adapter/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2023-04-07-redis-streams-adapter.md","source":"@site/blog/2023-04-07-redis-streams-adapter.md","title":"Redis Streams adapter","description":"Hello everyone!","date":"2023-04-07T00:00:00.000Z","formattedDate":"April 7, 2023","tags":[],"readingTime":0.55,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Redis Streams adapter","slug":"/socket-io-redis-streams-adapter/","authors":["darrachequesne"]},"prevItem":{"title":"Socket.IO on Azure","permalink":"/blog/socket-io-on-azure-preview/"},"nextItem":{"title":"Socket.IO server for Deno","permalink":"/blog/socket-io-deno/"}},"content":"Hello everyone!\\n\\nThere is a new official adapter for Socket.IO: the [Redis Streams adapter](/docs/v4/redis-streams-adapter/).\\n\\n\x3c!--truncate--\x3e\\n\\n:::note\\n\\nAn Adapter is a server-side component which is responsible for forwarding packets within a cluster of Socket.IO servers.\\n\\nMore information [here](/docs/v4/adapter/).\\n\\n:::\\n\\nThe adapter will use a [Redis stream](https://redis.io/docs/data-types/streams/) to forward packets between the Socket.IO servers.\\n\\nThe main difference with the existing Redis adapter (which use the [Redis Pub/Sub mechanism](https://redis.io/docs/manual/pubsub/)) is that this adapter will properly handle any temporary disconnection to the Redis server and resume the stream without losing any packets.\\n\\nSee also:\\n\\n- [Installation steps](/docs/v4/redis-streams-adapter/#installation)\\n- [Source code](https://github.com/socketio/socket.io-redis-streams-adapter)\\n\\nIf you have any feedback, feel free to open an issue in the repository."},{"id":"/socket-io-deno/","metadata":{"permalink":"/blog/socket-io-deno/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2022-09-13-deno.md","source":"@site/blog/2022-09-13-deno.md","title":"Socket.IO server for Deno","description":"Hello everyone!","date":"2022-09-13T00:00:00.000Z","formattedDate":"September 13, 2022","tags":[],"readingTime":0.61,"hasTruncateMarker":false,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO server for Deno","slug":"/socket-io-deno/","authors":"darrachequesne"},"prevItem":{"title":"Redis Streams adapter","permalink":"/blog/socket-io-redis-streams-adapter/"},"nextItem":{"title":"Socket.IO 4.5.0","permalink":"/blog/socket-io-4-5-0/"}},"content":"Hello everyone!\\n\\nI\'m happy to announce that Socket.IO is now compatible with [Deno](https://deno.land/), which is a runtime for JavaScript and TypeScript written in Rust.\\n\\nUsage:\\n\\n```ts\\nimport { serve } from \\"https://deno.land/[email protected]/http/server.ts\\";\\nimport { Server } from \\"https://deno.land/x/[email protected]/mod.ts\\";\\n\\nconst io = new Server();\\n\\nio.on(\\"connection\\", (socket) => {\\n  console.log(`socket ${socket.id} connected`);\\n\\n  socket.emit(\\"hello\\", \\"world\\");\\n\\n  socket.on(\\"disconnect\\", (reason) => {\\n    console.log(`socket ${socket.id} disconnected due to ${reason}`);\\n  });\\n});\\n\\nawait serve(io.handler(), {\\n  port: 3000,\\n});\\n```\\n\\nAnd then run with:\\n\\n```\\n$ deno run --allow-net index.ts\\n```\\n\\nThe API is very similar to the one exposed by the Node.js implementation.\\n\\nNext steps:\\n\\n- client implementation\\n- compatibility with the Node.js ecosystem (msgpack parser, adapters, admin UI, ...)\\n\\nFeedback is wel
1come!\\n\\n- Source code: https://github.com/socketio/socket.io-deno\\n- Module: https://deno.land/x/socket_io"},{"id":"/socket-io-4-5-0/","metadata":{"permalink":"/blog/socket-io-4-5-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2022-04-23-4.5.0.md","source":"@site/blog/2022-04-23-4.5.0.md","title":"Socket.IO 4.5.0","description":"Hello everyone!","date":"2022-04-23T00:00:00.000Z","formattedDate":"April 23, 2022","tags":[],"readingTime":1.69,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 4.5.0","slug":"/socket-io-4-5-0/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO server for Deno","permalink":"/blog/socket-io-deno/"},"nextItem":{"title":"Socket.IO 4.4.0","permalink":"/blog/socket-io-4-4-0/"}},"content":"Hello everyone!\\n\\nWe have just published a new minor version of Socket.IO: `4.5.0`\\n\\n\x3c!--truncate--\x3e\\n\\nHere are the new features in this release:\\n\\n## Catch-all listeners for outgoing packets\\n\\nThis is similar to [`onAny()`](/docs/v4/server-api/#socketonanycallback), but for outgoing packets.\\n\\nSyntax:\\n\\n```js\\nsocket.onAnyOutgoing((event, ...args) => {\\n  console.log(event);\\n});\\n```\\n\\nThis feature can be used on both sides, and will also work when [broadcasting events](/docs/v4/broadcasting-events/):\\n\\n```js\\nio.on(\\"connection\\", (socket) => {\\n  socket.onAnyOutgoing((event, ...args) => {\\n    console.log(event); // prints \\"some event\\"\\n  });\\n\\n  io.emit(\\"some event\\");\\n});\\n```\\n\\n## Multiple acknowledgements when broadcasting\\n\\nYou can now broadcast an event to multiple clients and expect an acknowledgement:\\n\\n```js\\nio.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```\\n\\n## Limit the number of packets sent in HTTP long-polling mode\\n\\nThe server will now include the value of the [`maxHttpBufferSize`](/docs/v4/server-options/#maxhttpbuffersize) in the handshake, so the clients will now be able to decide how many packets they have to send to stay under this value.\\n\\nHere is what the handshake will now look like:\\n\\n```\\n0{\\"sid\\":\\"lv_VI97HAXpY6yYWAAAC\\",\\"upgrades\\":[\\"websocket\\"],\\"pingInterval\\":25000,\\"pingTimeout\\":5000,\\"maxPayload\\":1000000}\\n```\\n\\nMore information [here](https://github.com/socketio/socket.io-client/issues/1531).\\n\\n## Disconnection details\\n\\nThe \\"disconnect\\" event on the client side will now include additional details to help debugging if anything has gone wrong.\\n\\nExample when [sticky session is not enabled](/docs/v4/using-multiple-nodes/#why-is-sticky-session-required):\\n\\n```js\\nsocket.on(\\"disconnect\\", (reason, details) => {\\n  console.log(details.context.status); // 400\\n  console.log(details.context.responseText); // \'{\\"code\\":1,\\"message\\":\\"Session ID unknown\\"}\'\\n});\\n```\\n\\nThis release also includes some bug fixes, please see the complete diff below.\\n\\n## Links\\n\\n- Server: [GitHub release](https://github.com/socketio/socket.io/releases/tag/4.5.0) / [Diff](https://github.com/socketio/socket.io/compare/4.4.1...4.5.0) / [npm](https://www.npmjs.com/package/socket.io/v/4.5.0)\\n- Client: [GitHub release](https://github.com/socketio/socket.io-client/releases/tag/4.5.0) / [Diff](https://github.com/socketio/socket.io-client/compare/4.4.1...4.5.0) / [npm](https://www.npmjs.com/package/socket.io-client/v/4.5.0)\\n\\nSize of the bundles:\\n\\n|                          | min                           | min+gzip                      |\\n|--------------------------|-------------------------------|-------------------------------|\\n| socket.io.min.js         | 42.6 KB (+ 2.2 KB :arrow_up:) | 13.6 KB (+ 0.5 KB :arrow_up:) |\\n| socket.io.msgpack.min.js | 47.7 KB (+ 2.1 KB :arrow_up:) | 14.6 KB (+ 0.4 KB :arrow_up:) |\\n| socket.io.esm.min.js     | 34.5 KB (+ 1.4 KB :arrow_up:) | 11.5 KB (+ 0.2 K
1B :arrow_up:) |\\n\\nThat\'s all for this release, thanks for reading!"},{"id":"/socket-io-4-4-0/","metadata":{"permalink":"/blog/socket-io-4-4-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-11-18-4.4.0.md","source":"@site/blog/2021-11-18-4.4.0.md","title":"Socket.IO 4.4.0","description":"Hello everyone!","date":"2021-11-18T00:00:00.000Z","formattedDate":"November 18, 2021","tags":[],"readingTime":1.635,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 4.4.0","slug":"/socket-io-4-4-0/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 4.5.0","permalink":"/blog/socket-io-4-5-0/"},"nextItem":{"title":"Socket.IO 4.3.0","permalink":"/blog/socket-io-4-3-0/"}},"content":"Hello everyone!\\n\\nWe have just published a new minor version of Socket.IO: `4.4.0`\\n\\n\x3c!--truncate--\x3e\\n\\nAfter a big focus on the client in the [latest release](./2021-10-15-4.3.0.md), this release is more oriented towards the server.\\n\\n## Support for \xb5WebSockets.js\\n\\nWhy should one choose between performance and reliability? Starting with `[email protected]`, you can now use the HTTP/WebSocket server provided by the [`\xb5WebSockets.js`](https://github.com/uNetworking/uWebSockets.js) package:\\n\\n```js\\nconst { App } = require(\\"uWebSockets.js\\");\\nconst { Server } = require(\\"socket.io\\");\\n\\nconst app = new 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```\\n\\nIt acts as a replacement for both the default Node.js HTTP server and the WebSocket server provided by the [`ws`](https://github.com/websockets/ws) package, and should improve the memory footprint and the latency of your application. Benchmarks coming soon!\\n\\n## Emit with timeout\\n\\nThere is a new `socket.timeout()` method available on both sides:\\n\\n```js\\nsocket.timeout(5000).emit(\\"my-event\\", (err) => {\\n  if (err) {\\n    // the other side did not acknowledge the event in the given delay\\n  }\\n});\\n```\\n\\n## `socket.data` can now be typed\\n\\nFor TypeScript users, the `socket.data` can now be typed:\\n\\n```ts\\ninterface SocketData {\\n  name: string;\\n  age: number;\\n}\\n\\nconst io = new Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>();\\n\\nio.on(\\"connection\\", (socket) => {\\n  socket.data.name = \\"john\\";\\n  socket.data.age = 42;\\n});\\n```\\n\\nThis release also includes some bug fixes, please see the complete diff below.\\n\\n## Links\\n\\n- Server: [GitHub release](https://github.com/socketio/socket.io/releases/tag/4.4.0) / [Diff](https://github.com/socketio/socket.io/compare/4.3.2...4.4.0) / [npm](https://www.npmjs.com/package/socket.io/v/4.4.0)\\n- Client: [GitHub release](https://github.com/socketio/socket.io-client/releases/tag/4.4.0) / [Diff](https://github.com/socketio/socket.io-client/compare/4.3.2...4.4.0) / [npm](https://www.npmjs.com/package/socket.io-client/v/4.4.0)\\n\\
1nSize of the bundles:\\n\\n| | min | min+gzip |\\n| --- | --- | --- |\\n| socket.io.min.js | 40.4 KB (+ 0.4 KB :arrow_up:) | 13.1 KB (+ 0.1 KB :arrow_up:) |\\n| socket.io.msgpack.min.js | 45.6 KB (+ 0.4 KB :arrow_up:) | 14.2 KB (-) |\\n| socket.io.esm.min.js | 33.1 KB (+ 0.3 KB :arrow_up:) | 11.3 KB (+ 0.2 KB :arrow_up:) |\\n\\nThat\'s all for this release, thanks for reading!"},{"id":"/socket-io-4-3-0/","metadata":{"permalink":"/blog/socket-io-4-3-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-10-15-4.3.0.md","source":"@site/blog/2021-10-15-4.3.0.md","title":"Socket.IO 4.3.0","description":"Hello everyone!","date":"2021-10-15T00:00:00.000Z","formattedDate":"October 15, 2021","tags":[],"readingTime":0.815,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 4.3.0","slug":"/socket-io-4-3-0/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 4.4.0","permalink":"/blog/socket-io-4-4-0/"},"nextItem":{"title":"Monthly update #5","permalink":"/blog/monthly-update-5/"}},"content":"Hello everyone!\\n\\nWe have just published a new minor version of Socket.IO: `4.3.0`\\n\\n\x3c!--truncate--\x3e\\n\\nAn ESM bundle is now provided:\\n\\n```html\\n<script type=\\"module\\">\\n  import { io } from \\"https://cdn.socket.io/4.3.0/socket.io.esm.min.js\\";\\n\\n  const socket = io();\\n\\n  socket.emit(\\"hello\\", \\"world\\");\\n<\/script>\\n```\\n\\nThe bundle size has been [greatly reduced](https://bundlephobia.com/package/[email protected]), thanks to:\\n\\n- the migration to [rollup](https://rollupjs.org)\\n- the cleanup of some unused code\\n- the removal of debug calls from the bundle (explanation [here](https://github.com/socketio/engine.io-client/commit/00d7e7d7ee85b4cfa6f9f547203cc692083ac61c))\\n\\nAnd finally, the Socket.IO client is now compatible with [Vite](https://vitejs.dev/) ([#1492](https://github.com/socketio/socket.io-client/issues/1492)).\\n\\n### Links\\n\\n- Server: [Release notes](https://github.com/socketio/socket.io/releases/tag/4.3.0) / [Diff](https://github.com/socketio/socket.io/compare/4.2.0...4.3.0)\\n- Client: [Release notes](https://github.com/socketio/socket.io-client/releases/tag/4.3.0) / [Diff](https://github.com/socketio/socket.io-client/compare/4.2.0...4.3.0)\\n- `ws` version: `~8.2.3` ([diff](https://github.com/websockets/ws/compare/7.4.2...8.2.3))\\n\\nSize of the bundles:\\n\\n| | min | min+gzip |\\n| --- | --- | --- |\\n| socket.io.min.js | 39.9 KB (-24.6 KB :arrow_down:) | 12.9 KB (-3.1 KB :arrow_down:) |\\n| socket.io.msgpack.min.js | 45.1 KB (-25.6 KB :arrow_down:) | 14 KB (-2.6 KB :arrow_down:) |\\n| socket.io.esm.min.js | 32.7 KB | 11.1 KB |\\n\\nThat\'s all for this release, thanks for reading!"},{"id":"/monthly-update-5/","metadata":{"permalink":"/blog/monthly-update-5/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-07-08-monthly-update-5.md","source":"@site/blog/2021-07-08-monthly-update-5.md","title":"Monthly update #5","description":"Hi everyone!","date":"2021-07-08T00:00:00.000Z","formattedDate":"July 8, 2021","tags":[],"readingTime":1.32,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Monthly update #5","slug":"/monthly-update-5/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 4.3.0","permalink":"/blog/socket-io-4-3-0/"},"nextItem":{"title":"Socket.IO 4.1.0","permalink":"/blog/socket-io-4-1-0/"}},"content":"Hi everyone!\\n\\nHere\'s the #5 edition of our Monthly update.\\n\\n\x3c!--truncate--\x3e\\n\\nSo, what\'s new in the Socket.IO ecosystem?\\n\\n- [A new API for inter-server communication](#a-new-api-for-inter-server-communication)\\n- [New official adapters](#new-official-adapters)\\n- [Additional documentation](#additional-documentation)\\n- [Version updates](#version-updates)\\n- [What\'s next](#whats-next)\\n\\n## A new API for inter-server communication\\n\\nThis feature had been requested for quite some time, it is now implemented in release 4.1.0. It allows to broadcast events between your Socket.IO servers.\\n\\nThe syntax is very similar to the existing one, except it\'s for server-to-server communication:\\n\\n```js\\nio.serverSideEmit(\\"hello\\", \\"world\\");
1\\n```\\n\\nAnd on the receiving side:\\n\\n```js\\nio.on(\\"hello\\", (arg1) => {\\n  console.log(arg1); // prints \\"world\\"\\n});\\n```\\n\\nAcknowledgements are supported too:\\n\\n```js\\n// 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```\\n\\nYou can find the complete release notes [here](/blog/socket-io-4-1-0/).\\n\\n## New official adapters\\n\\nHistorically, the Redis adapter was the only official adapter when scaling to multiple nodes.\\n\\nThere are now three additional official adapters:\\n\\n- the [MongoDB adapter](/docs/v4/mongo-adapter/)\\n- the [Postgres adapter](/docs/v4/postgres-adapter/)\\n- the [cluster adapter](/docs/v4/cluster-adapter/)\\n\\nNote: the first two were inspired from existing adapters maintained by the community and were updated to support Socket.IO v3.\\n\\nAll of them supports the [utility methods](/docs/v4/server-instance/#utility-methods) that were added in v4, including the `serverSideEmit()` method described above.\\n\\n## Additional documentation\\n\\n- usage with bundlers like webpack for the [client](/docs/v4/client-with-bundlers/) and the [server](/docs/v4/server-with-bundlers/)\\n- [usage with PM2](/docs/v4/pm2/)\\n\\n## Version updates\\n\\n- [[email protected]](https://github.com/socketio/socket.io/releases/tag/4.1.2)\\n- [[email protected]](https://github.com/socketio/socket.io-client/releases/tag/4.1.2)\\n\\n## What\'s next\\n\\n- a continuous focus on the documentation (additional code examples, extended guide, ...)\\n- additional tooling around Socket.IO\\n\\nHappy coding!"},{"id":"/socket-io-4-1-0/","metadata":{"permalink":"/blog/socket-io-4-1-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-05-14-4.1.0.md","source":"@site/blog/2021-05-14-4.1.0.md","title":"Socket.IO 4.1.0","description":"Hello everyone!","date":"2021-05-14T00:00:00.000Z","formattedDate":"May 14, 2021","tags":[],"readingTime":3.675,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 4.1.0","slug":"/socket-io-4-1-0/","authors":"darrachequesne"},"prevItem":{"title":"Monthly update #5","permalink":"/blog/monthly-update-5/"},"nextItem":{"title":"Monthly update #4","permalink":"/blog/monthly-update-4/"}},"content":"Hello everyone!\\n\\nWe have just published a new minor version of Socket.IO: [4.1.0](https://github.com/socketio/socket.io/releases/tag/4.1.0)\\n\\n\x3c!--truncate--\x3e\\n\\n## New features\\n\\n- [Add support for inter-server communication](#add-support-for-inter-server-communication)\\n- [Emit an event when a namespace is created](#emit-an-event-when-a-namespace-is-created)\\n- [Add a way to customize the response headers](#add-a-way-to-customize-the-response-headers)\\n- [Add a way to get access to the reason of a connection error](#add-a-way-to-get-access-to-the-reason-of-a-connection-error)\\n- [Add a way to ignore the `beforeunload` event](#add-a-way-to-ignore-the-beforeunload-event)\\n\\n### Add support for inter-server communication\\n\\nThis feature might be useful in a multi-server setup: you can now broadcast events between your Socket.IO servers.\\n\\nSyntax:\\n\\n```js\\nio.serverSideEmit(\\"hello\\", \\"world\\");\\n```\\n\\nAnd on the receiving side:\\n\\n```js\\nio.on(\\"hello\\", (arg1) => {\\n  console.log(arg1); // prints \\"world\\"\\n});\\n```\\n\\nAcknowledgements are supported too:\\n\\n```js\\n// 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```\\n\\nA few notes:\\n\\n- the events are specific to each [namespace](/docs/v4/namespaces/)\\n\\n```js\\n// server A\\nio.of(\\"/custom\\").serverSideEmit(\\"sync\\");\\n\\n// server B\\nio.of(\\"/custom\\").on(\\"sync\\", () => {\\n  // ...\\n});\\n```\\n\\n- the `connection`, `connect` and `new_namespace` (see [below](#emit-an-event-when-a-namespace-is-created)) strings are reserved and cannot be used in your application.\\n\\n- you can send any number of arguments, but binary structures are currently not supported (the array of arguments will be `JSON.stringify`-ed)\\n\\nExample:\\n\\n```js\\nio.serverSideEmit(\\"hello\\", \\"world\\", 1, \\"2\\", { 3: \\"4\\" });\\n```\\n\\nThe [Redis adapter](https://github.com/socketio/socket.io-redis-adapter) and its [associated emitter](https://github.com/socketio/socket.io-redis-emitter) have been updated to support this new functionality.\\n\\n### Emit an event when a namespace is created\\n\\nThe `new_namespace` event will be emitted by the Server instance when a new namespace is created:\\n\\n```js\\nio.on(\\"new_namespace\\", (namespace) 
1=> {\\n  // ...\\n});\\n```\\n\\nThis can be useful for example:\\n\\n- to attach a shared middleware to each namespace\\n\\n```js\\nio.on(\\"new_namespace\\", (namespace) => {\\n  namespace.use(myMiddleware);\\n});\\n```\\n\\n- to track the [dynamically created](/docs/v4/namespaces/#Dynamic-namespaces) namespaces\\n\\n```js\\nio.of(/\\\\/nsp-\\\\w+/);\\n\\nio.on(\\"new_namespace\\", (namespace) => {\\n  console.log(namespace.name);\\n});\\n```\\n\\n### Add a way to customize the response headers\\n\\nThe underlying Engine.IO server, which manages the low-level connection (HTTP long-polling and/or WebSocket), will now emit two additional events:\\n\\n- `initial_headers`\\n- `headers`\\n\\nLike the name suggests, the `initial_headers` event will be emitted only for the first HTTP request of the session, while the `headers` event will be emitted for each HTTP request (including the WebSocket upgrade).\\n\\nExample:\\n\\n```js\\nio.engine.on(\\"initial_headers\\", (headers, req) => {\\n  headers[\\"test\\"] = \\"123\\";\\n  headers[\\"set-cookie\\"] = \\"mycookie=456\\";\\n});\\n\\nio.engine.on(\\"headers\\", (headers, req) => {\\n  headers[\\"test\\"] = \\"789\\";\\n});\\n```\\n\\nNote: it was previously possible to achieve this by listening to the \\"request\\" event, but this should be easier with those new events:\\n\\n```js\\nconst httpServer = require(\\"http\\").createServer();\\nconst { Server } = require(\\"socket.io\\");\\nconst io = new Server(httpServer);\\n\\nhttpServer.prependListener(\\"request\\", (req, res) => {\\n  res.setHeader(\\"test\\", \\"789\\");\\n});\\n```\\n\\n### Add a way to get access to the reason of a connection error\\n\\nThe underlying Engine.IO server will also emit a new event: `connection_error`.\\n\\nSyntax:\\n\\n```js\\nio.engine.on(\\"connection_error\\", (err) => {\\n  console.log(err.req);\\t     // 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```\\n\\nHere is the list of possible error codes:\\n\\n| Code | Message |\\n|:----:|:-------:|\\n| 0 | \\"Transport unknown\\"\\n| 1 | \\"Session ID unknown\\"\\n| 2 | \\"Bad handshake method\\"\\n| 3 | \\"Bad request\\"\\n| 4 | \\"Forbidden\\"\\n| 5 | \\"Unsupported protocol version\\"\\n\\n### Add a way to ignore the `beforeunload` event\\n\\nA few months ago, a user [reported](https://github.com/socketio/socket.io/issues/3639) a weird behavior when reloading a page: on Firefox, the Socket instance would emit a `disconnect` event, but not on Chrome or Safari.\\n\\nWe have published a fix for this issue in `[email protected]`, by silently closing the connection when receiving a [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) event from the browser.\\n\\nUnfortunately, this fix had unintended consequences: if you relied on the `beforeunload` event to prompt the user for confirmation (\\"your last modifications are not saved yet, do you really want to leave?\\"), the Socket.IO connection would now be closed, even if the user decided to stay on the page.\\n\\nThat\'s why we have added the `closeOnBeforeunload` option, to give you total control over this behavior:\\n\\n```js\\nconst socket = io(\\"/\\", {\\n  closeOnBeforeunload: false // defaults to true\\n})\\n```\\n\\n- `closeOnBeforeunload: true` (the default value) will make all browsers behave the same (no `disconnect` event when reloading the page)\\n- `closeOnBeforeunload: false` will ignore the `beforeunload` event, but you will get a `disconnect` event on Firefox\\n\\nThat\'s all for this release, thanks for reading!"},{"id":"/monthly-update-4/","metadata":{"permalink":"/blog/monthly-update-4/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-05-06-monthly-update-4.md","source":"@site/blog/2021-05-06-monthly-update-4.md","title":"Monthly update #4","description":"Hi everyone!","date":"2021-05-06T00:00:00.000Z","formattedDate":"May 6, 2021","tags":[],"readingTime":1.225,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Monthly update #4","slug":"/monthly-update-4/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 4.1.0","permalink":"/blog/socket-io-4-1-0/"},"nextItem":{"title":"Socket.IO Admin UI","permalink":"/blog/admin-ui-first-release/"}},"content":"Hi everyone!\\n\\nHere\'s the #4 edition of our Monthly update.\\n\\n\x3c!--truncate--\x3e\\n\\nSo, what\'s new in the Socket.IO ecosystem?\\n\\n- [A new Admin UI](#a-new-admin-ui)\\n- [A new guide](#a-new-guide)\\n- [Version updates](#version-updates)\\n- [What\'s next](#whats-next)\\n\\n## A new Admin UI\\n\\
1nFollowing our focus on tooling, we have published a first release of the Socket.IO Admin UI:\\n\\n![admin UI screenshot](/images/admin-ui-dashboard.png)\\n\\nThis Admin UI is meant to give you an overview of your Socket.IO deployment.\\n\\nHere is the list of the current features:\\n\\n- overview of the servers and the clients that are currently connected\\n- details of each socket instance (active transport, handshake, rooms, ...)\\n- details of each room\\n- administrative operations (join, leave, disconnect)\\n\\nAnd the features which will be added in the near future:\\n\\n- overview of the number of packets/bytes sent and received per second\\n- emitting an event to all clients, a room or a particular Socket instance\\n\\nThe installation steps can be found [here](/docs/v4/admin-ui/).\\n\\nThe source code can be found here: https://github.com/socketio/socket.io-admin-ui/\\n\\nIf you have any feedback / suggestions, do not hesitate!\\n\\nPlease note that the Admin UI does support a cluster of several Socket.IO servers too.\\n\\n## A new guide\\n\\nWe have added a new guide ([here](/get-started/basic-crud-application/)), using Socket.IO to create a basic CRUD application.\\n\\n![Video of the application in action](/images/basic-crud-app.gif)\\n\\n## Version updates\\n\\n- [[email protected]](https://github.com/socketio/socket.io/releases/tag/4.0.2)\\n- [[email protected]](https://github.com/socketio/socket.io-client/releases/tag/4.0.2)\\n\\n## What\'s next\\n\\n- a continuous focus on the documentation (additional code examples, extended guide, ...)\\n- additional tooling around Socket.IO\\n\\nHappy coding!"},{"id":"/admin-ui-first-release/","metadata":{"permalink":"/blog/admin-ui-first-release/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-04-16-admin-ui.md","source":"@site/blog/2021-04-16-admin-ui.md","title":"Socket.IO Admin UI","description":"Hi everyone!","date":"2021-04-16T00:00:00.000Z","formattedDate":"April 16, 2021","tags":[],"readingTime":0.39,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO Admin UI","slug":"/admin-ui-first-release/","authors":"darrachequesne"},"prevItem":{"title":"Monthly update #4","permalink":"/blog/monthly-update-4/"},"nextItem":{"title":"Monthly update #3","permalink":"/blog/monthly-update-3/"}},"content":"Hi everyone!\\n\\nWe have published a first release of the Socket.IO Admin UI:\\n\\n![admin UI screenshot](/images/admin-ui-dashboard.png)\\n\\n\x3c!--truncate--\x3e\\n\\nCurrent features:\\n\\n- overview of the servers and the clients that are currently connected\\n- details of each socket instance (active transport, handshake, rooms, ...)\\n- details of each room\\n- administrative operations (join, leave, disconnect)\\n\\nThe installation steps can be found [here](/docs/v4/admin-ui/).\\n\\nThe source code can be found here: https://github.com/socketio/socket.io-admin-ui/\\n\\nIf you have any feedback / suggestions, do not hesitate!"},{"id":"/monthly-update-3/","metadata":{"permalink":"/blog/monthly-update-3/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-04-07-monthly-update-3.md","source":"@site/blog/2021-04-07-monthly-update-3.md","title":"Monthly update #3","description":"Hi everyone!","date":"2021-04-07T00:00:00.000Z","formattedDate":"April 7, 2021","tags":[],"readingTime":2.28,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Monthly update #3","slug":"/monthly-update-3/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO Admin UI","permalink":"/blog/admin-ui-first-release/"},"nextItem":{"title":"Socket.IO 4.0.0","permalink":"/blog/socket-io-4-release/"}},"content":"Hi everyone!\\n\\nHere\'s the #3 edition of our Monthly update.\\n\\n\x3c!--truncate--\x3e\\n\\nSo, what\'s new in the Socket.IO ecosystem?\\n\\n- [Socket.IO v4](#socketio-v4)\\n- [Redis Adapter v6.1.0 and Redis Emitter v4.0.0](#redis-adapter-v610-and-redis-emitter-v400)\\n- [Documentation](#documentation)\\n- [New versions](#new-versions)\\n- [What\'s next](#whats-next)\\n\\n## Socket.IO v4\\n\\nWait, already v4?\\n\\nYes, but the upgrade should be a lot easier than from v2 to v3, since the two breaking changes only impact the API on the server side.\\n\\nThe most important breaking change is related to broadcasting: calling `to()` or any other broadcast modifier will now return an immutable object.\\n\\nPreviously, the modifiers were saved on the `io` instance directly, which could lead to surprising behaviors:\\n\\n```js\\nio.to(\\"room1\\");
1\\n// and then later\\nio.to(\\"room2\\").emit(/* ... */); // also sent to room1\\n```\\n\\nYou were also not able to reuse the operator:\\n\\n```js\\nconst operator = io.to(\\"room1\\");\\n\\noperator.emit(/* ... */); // to room1 (assuming synchronous call)\\noperator.emit(/* ... */); // to all clients\\n```\\n\\nEven more surprising, with asynchronous code:\\n\\n```js\\nio.to(\\"room3\\").emit(\\"details\\", await fetchDetails()); // unspecified behavior: maybe in room3, maybe to all clients\\n```\\n\\nStarting with v4.0.0, you can now use `io.to()` safely:\\n\\n```js\\nconst operator = io.to(\\"room1\\").except(\\"room2\\");\\n\\noperator.emit(/* ... */);\\noperator.emit(/* ... */);\\n```\\n\\nThis release also brings some interesting new features, like the `fetchSockets()` method.\\n\\nPlease check the migration guide [here](/docs/v4/migrating-from-3-x-to-4-0/).\\n\\n## Redis Adapter v6.1.0 and Redis Emitter v4.0.0\\n\\nThe Redis adapter (for broadcasting packets with multiple Socket.IO servers) and the Redis emitter (for broadcasting packets from another Node.js process) have been updated in order to support the [new features](/docs/v4/migrating-from-3-x-to-4-0/#new-features) of the v4 release.\\n\\nFor example, the `socketsJoin` method will work across Socket.IO servers:\\n\\n```js\\n// 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\\nMore information can be found [here](/docs/v4/server-instance/#utility-methods).\\n\\n## Documentation\\n\\nThe documentation continues to be improved.\\n\\nA new example project has been added in the \\"Get started\\" section, with middlewares and rooms: [Private messaging](/get-started/private-messaging-part-1/)\\n\\nAs usual, if you find a typo or think that some details are missing, please open an issue here: https://github.com/socketio/socket.io-website\\n\\n## New versions\\n\\n- [[email protected]](https://github.com/socketio/socket.io/releases/tag/4.0.1) ([release notes](/blog/socket-io-3-release/))\\n  - [[email protected]](https://github.com/socketio/engine.io-parser/releases/tag/4.0.2) (included in `socket.io{% raw %}@{% endraw %}4.0.1`)\\n  - [[email protected]](https://github.com/socketio/engine.io/releases/tag/5.0.0) (included in `socket.io{% raw %}@{% endraw %}4.0.1`)\\n  - [[email protected]](https://github.com/socketio/socket.io-parser/releases/tag/4.0.4) (included in `socket.io{% raw %}@{% endraw %}4.0.1`)\\n\\n- [[email protected]](https://github.com/socketio/socket.io-client/releases/tag/4.0.1)\\n  - [[email protected]](https://github.com/socketio/engine.io-parser/releases/tag/4.0.2) (included in `socket.io-client{% raw %}@{% endraw %}4.0.1`)\\n  - [[email protected]](https://github.com/socketio/engine.io-client/releases/tag/5.0.1) (included in `socket.io-client{% raw %}@{% endraw %}4.0.1`)\\n  - [[email protected]](https://github.com/socketio/socket.io-parser/releases/tag/4.0.4) (included in `socket.io-client{% raw %}@{% endraw %}4.0.1`)\\n\\n- [[email protected]](https://github.com/socketio/socket.io-redis/releases/tag/6.1.0)\\n- [@socket.io/[email protected]](https://github.com/socketio/socket.io-redis-emitter/releases/tag/4.0.0)\\n\\n## What\'s next\\n\\n- a continuous focus on the documentation (additional code examples, extended guide, ...)\\n- additional tooling around Socket.IO\\n\\nStay safe!"},{"id":"/socket-io-4-release/","metadata":{"permalink":"/blog/socket-io-4-release/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-03-10-4.0.0.md","source":"@site/blog/2021-03-10-4.0.0.md","title":"Socket.IO 4.0.0","description":"Hello everyone!","date":"2021-03-10T00:00:00.000Z","formattedDate":"March 10, 2021","tags":[],"readingTime":0.92,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 4.0.0","slug":"/socket-io-4-release/","authors":"darrachequesne"},"prevItem":{"title":"Monthly update #3","permalink":"/blog/monthly-update-3/"},"nextItem":{"title":"Socket.IO 3.1.0","permalink":"/blog/socket-io-3-1-0/"}},"content":"Hello everyone!\\n\\nWe just published a new major version of Socket.IO: [4.0.0](https://github.com/socketio/socket.io/releases/tag/4.0.0)\\n\\n\x3c!--truncate--\x3e\\n\\nPlease see the associated [migration guide](/docs/v4/migrating-from-3-x-to-4-0/).\\n\\n**TL;DR:** this major bump is due to a few breaking changes at the API level.\\n\\nApart from this, the Socket.IO protocol was not updated, so a v3 client **will** be able to reach a v4 server and vice-versa. Besides, the compatibility mode ([`allowEIO3: true`](/docs/v4/server-options/#alloweio3)) is still available between a Socket.IO v2 client and a Socket.IO v4 server.\\n\\n### Bug Fixes (server)\\n\\n* make io.to(...) immutable ([ac9e8ca](https://github.com/socketio/socket.io/commit/ac9e8ca6c71e00d4af45ee03f590fe56f3951186))\\n* set default protocol version to 3 ([#616](https://github.com/socketio/engine.io/issues/616)) ([868d891](https://github.com/socketio/engine.io/commit/868d89111de0ab5bd0e147ecaff7983afbf5d087)) (Engine.IO)\\n\\n### Bug Fixes (client)\\n\\n* **bundle:** restore support for JS modules ([43613d1](https://github.com/socketio/socket.io-client/commit/43613d1b2c3c04e89d572750656012f54d44467c))\\n\\
1n### Features (server)\\n\\n* add some utility methods ([b25495c](https://github.com/socketio/socket.io/commit/b25495c069031674da08e19aed68922c7c7a0e28))\\n* add support for typed events ([#3822](https://github.com/socketio/socket.io/issues/3822)) ([0107510](https://github.com/socketio/socket.io/commit/0107510ba8a0f148c78029d8be8919b350feb633))\\n* allow to exclude specific rooms when broadcasting ([#3789](https://github.com/socketio/socket.io/issues/3789)) ([7de2e87](https://github.com/socketio/socket.io/commit/7de2e87e888d849eb2dfc5e362af4c9e86044701))\\n* allow to pass an array to io.to(...) ([085d1de](https://github.com/socketio/socket.io/commit/085d1de9df909651de8b313cc6f9f253374b702e))\\n* increase the default value of pingTimeout ([5a7fa13](https://github.com/socketio/engine.io/commit/5a7fa132c442bc1e7eefa1cf38168ee951575ded)) (Engine.IO)\\n* remove dynamic require() with wsEngine ([edb7343](https://github.com/socketio/engine.io/commit/edb734316f143bf0f1bbc344e966d18e2676b934)) (Engine.IO)\\n\\n### Features (client)\\n\\n* add autoUnref option ([
16abfa1f](https://github.com/socketio/socket.io-client/commit/6abfa1fa4c7fea0d69c69b254d2e1ca18f19c4bc))\\n* add support for typed events ([5902365](https://github.com/socketio/socket.io-client/commit/59023657a02cf78f90522e0d7797749707ed5ed2))\\n* listen to the \\"offline\\" event ([c361bc6](https://github.com/socketio/engine.io-client/commit/c361bc691f510b96f8909c5e6c62a4635d50275c)) (Engine.IO client)"},{"id":"/socket-io-3-1-0/","metadata":{"permalink":"/blog/socket-io-3-1-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-01-15-3.1.0.md","source":"@site/blog/2021-01-15-3.1.0.md","title":"Socket.IO 3.1.0","description":"Hello everyone!","date":"2021-01-15T00:00:00.000Z","formattedDate":"January 15, 2021","tags":[],"readingTime":1.42,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 3.1.0","slug":"/socket-io-3-1-0/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 4.0.0","permalink":"/blog/socket-io-4-release/"},"nextItem":{"title":"Socket.IO 2.4.0","permalink":"/blog/socket-io-2-4-0/"}},"content":"Hello everyone!\\n\\nWe just published a new version of Socket.IO: [3.1.0](https://github.com/socketio/socket.io/releases/tag/3.1.0)\\n\\n\x3c!--truncate--\x3e\\n\\nIn order to ease the migration to Socket.IO v3, the v3 server is now able to communicate with v2 clients:\\n\\n```js\\nconst io = require(\\"socket.io\\")({\\n  allowEIO3: true // false by default\\n});\\n```\\n\\nThis should make the migration easier for existing deployments:\\n\\n- first, update the servers with `allowEIO3` set to `true`\\n\\n```js\\nconst io = require(\\"socket.io\\")({\\n  allowEIO3: true // false by default\\n});\\n```\\n\\nNote: If you are using the Redis adapter to [broadcast packets between nodes](/docs/v3/broadcasting-events/#With-multiple-Socket-IO-servers), you must use `socket.io-redis@5` with `socket.io@2` and `socket.io-redis@6` with `socket.io@3`. Please note that both versions are compatible, so you can update each server one by one (no big bang is needed).\\n\\n- then, update the clients\\n\\nThis step may actually take some time, as some clients may still have a v2 client in cache.\\n\\nYou can check the version of the connection with:\\n\\n```js\\nio.on(\\"connection\\", (socket) => {\\n  const version = socket.conn.protocol; // either 3 or 4\\n});\\n```\\n\\nThis matches the value of the `EIO` query parameter in the HTTP requests.\\n\\n- and finally, once every client was updated, set `allowEIO3` to `false` (which is the default value)\\n\\n```js\\nconst io = require(\\"socket.io\\")({\\n  allowEIO3: false\\n});\\n```\\n\\nWith `allowEIO3` set to `false`, v2 clients will now receive an HTTP 400 error (`Unsupported protocol version`) when connecting.\\n\\nThe [migration guide](/docs/v3/migrating-from-2-x-to-3-0/) was updated accordingly.\\n\\n### Features\\n\\n* confirm a weak but matching ETag ([#3485](https://github.com/socketio/socket.io/issues/3485)) ([161091d](https://github.com/socketio/socket.io/commit/161091dd4c9e1b1610ac3d45d964195e63d92b94))\\n* **esm:** export the Namespace and Socket class ([#3699](https://github.com/socketio/socket.io/issues/3699)) ([233650c](https://github.com/socketio/socket.io/commit/233650c22209708b5fccc4349c38d2fa1b465d8f))\\n* add support for Socket.IO v2 clients ([9925746](https://github.com/socketio/socket.io/commit/9925746c8ee3a6522bd640b5d586c83f04f2f1ba))\\n* add room events ([155fa63](https://github.com/socketio/socket.io-adapter/commit/155fa6333a504036e99a33667dc0397f6aede25e))\\n\\n\\n### Bug Fixes\\n\\
1n* **typings:** make Manager#opts public ([#1437](https://github.com/socketio/socket.io-client/issues/1437)) ([fe97243](https://github.com/socketio/socket.io-client/commit/fe97243fab02cd80fc1116e8f4aeca02951dac75))\\n* allow integers as event names ([1c220dd](https://github.com/socketio/socket.io-parser/commit/1c220ddbf45ea4b44bc8dbf6f9ae245f672ba1b9))"},{"id":"/socket-io-2-4-0/","metadata":{"permalink":"/blog/socket-io-2-4-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2021-01-05-2.4.0.md","source":"@site/blog/2021-01-05-2.4.0.md","title":"Socket.IO 2.4.0","description":"Happy New Year everyone!","date":"2021-01-05T00:00:00.000Z","formattedDate":"January 5, 2021","tags":[],"readingTime":1.195,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 2.4.0","slug":"/socket-io-2-4-0/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 3.1.0","permalink":"/blog/socket-io-3-1-0/"},"nextItem":{"title":"Monthly update #2","permalink":"/blog/monthly-update-2/"}},"content":"Happy New Year everyone!\\n\\nWe just published a new minor version in the 2.x branch!\\n\\n\x3c!--truncate--\x3e\\n\\nPlease note that this release contains a breaking change regarding [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (CORS).\\n\\n**UPDATE**: this change was reverted in [2.4.1](https://github.com/socketio/socket.io/releases/tag/2.4.1), because it did not follow semantic versioning and broke some deployments (discussed [here](https://github.com/socketio/socket.io/discussions/3741)). Please make sure you are properly [securing your application](/docs/v2/handling-cors), and [upgrade](/docs/v3/migrating-from-2-x-to-3-0/) to Socket.IO v3 as soon as possible.\\n\\nPreviously, CORS was enabled by default, which meant that a Socket.IO server sent the necessary CORS headers (`Access-Control-Allow-xxx`) to **any** domain. This will not be the case anymore, and you now have to explicitly enable it.\\n\\nPlease note that you are not impacted if:\\n\\n- you are using Socket.IO v2 and the `origins` option to restrict the list of allowed domains\\n- you are using Socket.IO v3 (disabled by default)\\n\\nThis change also removes the support for \'*\' matchers and protocol-less URL:\\n\\n```\\nio.origins(\'https://example.com:443\'); => io.origins([\'https://example.com\']);\\nio.origins(\'localhost:3000\');          => io.origins([\'http://localhost:3000\']);\\nio.origins(\'http://localhost:*\');      => io.origins([\'http://localhost:3000\']);\\nio.origins(\'*:3000\');                  => io.origins([\'http://localhost:3000\']);\\n```\\n\\nTo restore the previous behavior (please use with caution):\\n\\n```js\\nio.origins((_, callback) => {\\n  callback(null, true);\\n});\\n```\\n\\nA big thanks to [@ni8walk3r](https://github.com/ni8walk3r) for the detailed security report.\\n\\nSee also:\\n\\n- https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\\n- https://socket.io/docs/v2/handling-cors/\\n\\n### Features\\n\\n* add support for all cookie options ([19cc582](https://github.com/socketio/engine.io/commit/19cc58264a06dca47ed401fbaca32dcdb80a903b))\\n* disable perMessageDeflate by default ([5ad2736](https://github.com/socketio/engine.io/commit/5ad273601eb66c7b318542f87026837bf9dddd21))\\n\\n### Bug Fixes\\n\\
1n* **security:** do not allow all origins by default ([f78a575](https://github.com/socketio/socket.io/commit/f78a575f66ab693c3ea96ea88429ddb1a44c86c7))\\n* properly overwrite the query sent in the handshake ([d33a619](https://github.com/socketio/socket.io/commit/d33a619905a4905c153d4fec337c74da5b533a9e))\\n\\n\\nStay safe!"},{"id":"/monthly-update-2/","metadata":{"permalink":"/blog/monthly-update-2/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2020-11-23-monthly-update.md","source":"@site/blog/2020-11-23-monthly-update.md","title":"Monthly update #2","description":"Hi everyone!","date":"2020-11-23T00:00:00.000Z","formattedDate":"November 23, 2020","tags":[],"readingTime":1.65,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Monthly update #2","slug":"/monthly-update-2/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 2.4.0","permalink":"/blog/socket-io-2-4-0/"},"nextItem":{"title":"Redis Adapter v6.0.0","permalink":"/blog/socket-io-redis-adapter-6-release/"}},"content":"Hi everyone!\\n\\nHere\'s the #2 edition of our Monthly update. This is a new experiment, we will try to stick to this frequency in order to keep you updated of the work in progress and the directions the project is taking.\\n\\n\x3c!--truncate--\x3e\\n\\nSo, what\'s new in the Socket.IO ecosystem?\\n\\n## Socket.IO v3\\n\\nAs announced in the [previous](/blog/monthly-update-2/) monthly update, Socket.IO v3 has been released a few days ago.\\n\\nThis major version bump is mandated by several necessary changes in the Engine.IO protocol. You can find more information about these changes in the [Engine.IO v4 release notes](/blog/engine-io-4-release/).\\n\\nYou can find the release notes [here](/blog/socket-io-3-release/) and the migration guide [here](/docs/v3/migrating-from-2-x-to-3-0/).\\n\\nLet\'s discuss about this release here: https://github.com/socketio/socket.io/discussions/3674\\n\\n## Redis Adapter v6\\n\\nFollowing the [release of Socket.IO v3.0.0](/blog/socket-io-3-release/), the Redis Adapter was updated and a new release is out: [6.0.0](https://github.com/socketio/socket.io-redis/releases/tag/6.0.0)\\n\\nYou can find the release notes [here](/blog/socket-io-redis-adapter-6-release/).\\n\\n## Documentation\\n\\nThe documentation has always been a weak point of the project, leading to a lot of issues opened on GitHub and questions on StackOverflow.\\n\\nNow that v3 is out, we will focus on this. The following pages have already been created:\\n\\n- [Emitting events](/docs/v3/emitting-events/)\\n- [Broadcasting events](/docs/v3/broadcasting-events/)\\n- [The Socket instance / server-side](/docs/v3/server-socket-instance/)\\n- [Middlewares](/docs/v3/middlewares/)\\n- [Handling CORS](/docs/v3/handling-cors/)\\n\\nIf you find a typo, please open an issue here: https://github.com/socketio/socket.io-website\\n\\n## Minor bumps\\n\\n- [[email protected]](https://github.com/socketio/socket.io/releases/tag/3.0.3) ([release notes](/blog/socket-io-3-release/))\\n  - [[email protected]](https://github.com/socketio/engine.io-parser/releases/tag/4.0.1) (included in `socket.io{% raw %}@{% endraw %}3.0.3`)\\n  - [[email protected]](https://github.com/socketio/engine.io/releases/tag/4.0.4) (included in `socket.io{% raw %}@{% endraw %}3.0.3`)\\n  - [[email protected]](https://github.com/socketio/socket.io-parser/releases/tag/4.0.1) (included in `socket.io{% raw %}@{% endraw %}3.0.3`)\\n\\n- [[email protected]](https://github.com/socketio/socket.io-client/releases/tag/3.0.3)\\n  - [[email protected]](https://github.com/socketio/engine.io-parser/releases/tag/4.0.1) (included in `socket.io-client{% raw %}@{% endraw %}3.0.3`)\\n  - [[email protected]](https://github.com/socketio/engine.io-client/releases/tag/4.0.4) (included in `socket.io-client{% raw %}@{% endraw %}3.0.3`)\\n  - [[email protected]](https://github.com/socketio/socket.io-parser/releases/tag/4.0.1) (included in `socket.io-client{% raw %}@{% endraw %}3.0.3`)\\n\\n- [[email protected]](https://github.com/socketio/socket.io-redis/releases/tag/6.0.1)\\n\\n- [[email protected]](https://github.com/socketio/socket.io-msgpack-parser/releases/tag/3.0.1)\\n\\nMore information about how to use those custom parsers can be found [here](https://github.com/socketio/socket.io/tree/master/examples/custom-parsers).\\n\\n## What\'s next\\n\\n- the client implementations in other languages will be updated as well\\n\\n- a big focus on the documentation (additional code examples, extended guide, ...)\\n\\n- additional tooling around Socket.IO\\n\\nStay safe!"},{"id":"/socket-io-redis-adapter-6-release/","metadata":{"permalink":"/blog/socket-io-redis-adapter-6-release/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2020-11-12-socket-io-redis-6.md","source":"@site/blog/2020-11-12-socket-io-redis-6.md","title":"Redis Adapter v6.0.0","description":"Following the release of Socket.IO v3.0.0, the Redis Adapter was updated and a new release is out: 6.0.0","date":"2020-11-12T00:00:00.000Z","formattedDate":"November 12, 2020","tags":[],"readingTime":1.14,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Redis Adapter v6.0.0","slug":"/socket-io-redis-adapter-6-release/","authors":"darrachequesne"},"prevItem":{"title":"Monthly update #2","permalink":"/blog/monthly-update-2/"},"nextItem":{"title":"Socket.IO 3 Release","permalink":"/blog/socket-io-3-release/"}},"content":"Following the [release of Socket.IO v3.0.0](/blog/socket-io-3-release/), the Redis Adapter was updated and a new release is out: [6.0.0](https://github.com/socketio/socket.io-redis/releases/tag/6.0.0)\\
1n\\n\x3c!--truncate--\x3e\\n\\nFor reference, the Redis Adapter is used when broadcasting packets across a set of Socket.IO servers. It relies on Redis [Pub/Sub mechanism](https://redis.io/topics/pubsub).\\n\\nMore information about how it works: https://github.com/socketio/socket.io-redis/#how-does-it-work-under-the-hood\\n\\nThe release notes can be found here: https://github.com/socketio/socket.io-redis/releases/tag/6.0.0\\n\\nPlease note that the new release is not compatible with Socket.IO v2, and previous versions are not compatible with Socket.IO v3 ([compatibility table](https://github.com/socketio/socket.io-redis/#compatibility-table)).\\n\\n## Notable changes\\n\\n### All the requests (for inter-node communication) now return a Promise instead of accepting a callback\\n\\nThe Redis Adapter exposes additional methods for managing sockets and rooms in a multi-node setup:\\n\\n- `RedisAdapter.sockets()`: returns the list of Socket IDs\\n- `RedisAdapter.allRooms()`: returns the list of all rooms.\\n- `RedisAdapter.remoteJoin(id, room)`: make the socket join the room\\n- `RedisAdapter.remoteLeave(id, room)`: make the socket leave the room\\n- `RedisAdapter.remoteDisconnect(id, close)`: disconnect the socket with the given id\\n\\nThose methods used to accept a callback argument, they will now return a Promise.\\n\\nBefore:\\n\\n```js\\nio.of(\'/\').adapter.allRooms((err, rooms) => {\\n  console.log(rooms); // an array containing all rooms (across all nodes)\\n});\\n```\\n\\nAfter:\\n\\n```js\\nconst rooms = await io.of(\'/\').adapter.allRooms();\\nconsole.log(rooms); // a Set containing all rooms (across all nodes)\\n```\\n\\n### customHook and customRequest methods were removed\\n\\nThose methods will be replaced by a more intuitive API in a future iteration."},{"id":"/socket-io-3-release/","metadata":{"permalink":"/blog/socket-io-3-release/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2020-11-05-socket-io-3.md","source":"@site/blog/2020-11-05-socket-io-3.md","title":"Socket.IO 3 Release","description":"We are happy to announce the release of Socket.IO v3!","date":"2020-11-05T00:00:00.000Z","formattedDate":"November 5, 2020","tags":[],"readingTime":2.085,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 3 Release","slug":"/socket-io-3-release/","authors":"darrachequesne"},"prevItem":{"title":"Redis Adapter v6.0.0","permalink":"/blog/socket-io-redis-adapter-6-release/"},"nextItem":{"title":"Monthly update #1","permalink":"/blog/monthly-update-1/"}},"content":"We are happy to announce the release of Socket.IO v3!\\n\\n\x3c!--truncate--\x3e\\n\\n## Migration guide\\n\\nThis release contains a few non backward compatible changes.\\n\\nWe have published a dedicated [migration guide](/docs/v4/migrating-from-2-x-to-3-0/) with all necessary details.\\n\\n\\n## Why Socket.IO in 2020?\\n\\nThat\'s an excellent question actually. Depending on your use case, it might make sense to use plain WebSocket directly:\\n\\n- client: [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket), [Can I use?](https://caniuse.com/websockets)\\n- server: [ws](https://github.com/websockets/ws) or [eiows](https://github.com/mmdevries/eiows) in the Node.JS ecosystem\\n\\nWhat Socket.IO brings:\\n\\n- a fallback to HTTP long-polling, in case the WebSocket connection cannot be established\\n\\nTo be honest, this feature was awesome 10 years ago, when most browsers didn\'t support WebSocket, but this is not the case anymore. That\'s still a great safety net though.\\n\\n- auto-reconnection\\n\\nUsing plain WebSocket, you can take a look at [robust-websocket](https://github.com/appuri/robust-websocket).\\n\\n- a classic request-response API: acknowledgements\\n\\n```js\\n// on one side\\nsocket.emit(\\"updateitem\\", \\"1\\", { name: \\"updated\\" }, (response) => {\\n  console.log(response.status); // ok\\n});\\n// on the other\\nsocket.on(\\"updateitem\\", (arg1, arg2, callback) => {\\n  console.log(arg1); // 1\\n  console.log(arg2); // { name: \\"updated\\" }\\n  callback({\\n    status: \\"ok\\"\\n  });\\n});\\n```\\n\\n- a way to broadcast data to a given set of clients: [Rooms](/docs/v4/rooms/)\\n\\n```js\\n// server-side\\nio.on(\\"connection\\", (socket) => {\\n  socket.join(\\"room1\\");
1\\n\\n  io.to(\\"room1\\").emit(\\"hello!\\");\\n});\\n```\\n\\nWhich also works when scaling to several Socket.IO servers (more information [here](/docs/v4/using-multiple-nodes/)).\\n\\n- a way to split your application logic into distinct modules (for more complex applications): [Namespaces](/docs/v4/namespaces/)\\n\\n```js\\n// server-side\\nconst adminNamespace = io.of(\\"/admin\\");\\n\\nadminNamespace.use((socket, next) => {\\n  // ensure the socket is authorized\\n});\\n\\nadminNamespace.on((socket) => {\\n  socket.on(\\"delete project\\", (id) => {\\n    // in all handlers, we are sure that the socket is authorized\\n  });\\n});\\n\\nadminNamespace.emit(\\"hello!\\"); // broadcast to admin only\\n```\\n\\n- an ecosystem of compatible clients in other languages\\n\\n    - Java: https://github.com/socketio/socket.io-client-java\\n    - C++: https://github.com/socketio/socket.io-client-cpp\\n    - Swift: https://github.com/socketio/socket.io-client-swift\\n    - Dart: https://github.com/rikulo/socket.io-client-dart\\n    - Python: https://github.com/miguelgrinberg/python-socketio\\n    - .Net: https://github.com/Quobject/SocketIoClientDotNet\\n\\n\\n\\n## What\'s next\\n\\n- the Redis adapter (used when broadcasting across Socket.IO servers) will be updated in order to be compatible with Socket.IO v3 (update: [done!](/blog/socket-io-redis-adapter-6-release/))\\n\\n- the client implementations in other languages will be updated as well\\n  - Java client: [done!](https://github.com/socketio/socket.io-client-java/releases/tag/socket.io-client-2.0.0)\\n  - C++ client: [done!](https://github.com/socketio/socket.io-client-cpp/releases/tag/3.0.0)\\n  - Swift: [done!](https://github.com/socketio/socket.io-client-swift/releases/tag/v16.0.0)\\n\\n- a big focus on the documentation (additional code examples, extended guide, ...)\\n\\n- additional tooling around Socket.IO\\n\\n\\n## Let\'s discuss!\\n\\nThe project is now part of the beta of Github Discussions. Depending on the feedback of the community, it might replace the Slack channel in the future.\\n\\nIf you have any question about the release, let\'s discuss [here](https://github.com/socketio/socket.io/discussions/3674).\\n\\n\\n\\nStay safe!"},{"id":"/monthly-update-1/","metadata":{"permalink":"/blog/monthly-update-1/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2020-10-03-monthly-update.md","source":"@site/blog/2020-10-03-monthly-update.md","title":"Monthly update #1","description":"Hi everyone!","date":"2020-10-03T00:00:00.000Z","formattedDate":"October 3, 2020","tags":[],"readingTime":2.12,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Monthly update #1","slug":"/monthly-update-1/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 3 Release","permalink":"/blog/socket-io-3-release/"},"nextItem":{"title":"Socket.IO client 2.3.1","permalink":"/blog/socket-io-2-3-1/"}},"content":"Hi everyone!\\n\\nHere\'s the #1 edition of our Monthly update. This is a new experiment, we will try to stick to this frequency in order to keep you updated of the work that is in progress and the directions the project is taking.\\n\\n\x3c!--truncate--\x3e\\n\\nSo, what\'s new in the Socket.IO ecosystem?\\n\\n## Socket.IO v3 (WIP)\\n\\nThe work on Socket.IO v3 has started (let\'s be honest and not say resumed).\\n\\nThis major version bump is mandated by several necessary changes in the Engine.IO protocol. You can find more information about these changes in the [Engine.IO v4 release notes](/blog/engine-io-4-release/).\\n\\nIt mostly impacts the way packets are encoded when sent over the wire (in the request/response body in case of HTTP long-polling, or in the WebSocket frames), so the public API of Socket.IO should not be impacted that much.\\n\\nWe will also take advantage of this new version to migrate the codebase to Typescript, so the typings which are currently hosted in the [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) will now always be in sync with the actual code.\\n\\nYou can follow the progress [here](https://github.com/socketio/socket.io/projects/2).\\n\\nIf you have any feedback/feature that you would like to see included, please comment [here](https://github.com/socketio/socket.io/issues/3250).\\n\\n## Engine.IO v4\\n\\nAs part of the work towards Socket v3, Engine.IO v4 has been released.\\n\\nThe list of breaking changes can be found in the [release notes](/blog/engine-io-4-release/).\\n\\n## Protocol documentation\\n\\nThe documentation of the [Engine.IO](https://github.com/socketio/engine.io-protocol) and the [Socket.IO](https://github.com/socketio/socket.io-protocol) protocols has been edited with additional details/examples.\\n\\nThis should help greatly when implementing a client in another programming language.\\n\\nIf you find that something is not clear/is missing, please open an issue in the repository.\\n\\nFor reference, here\'s the current list of clients in other languages:\\n\\n- Java: https://github.com/socketio/socket.io-client-java\\n- C++: https://github.com/socketio/socket.io-client-cpp\\n- Swift: https://github.com/socketio/socket.io-client-swift\\n- Dart: https://github.com/rikulo/socket.io-client-dart\\n- Python: https://github.com/miguelgrinberg/python-socketio\\n- .Net: https://github.com/Quobject/SocketIoClientDotNet\\n\\n\\
1n## GitHub discussions\\n\\nThe project is now part of the beta of Github Discussions. Depending on the feedback of the community, it might replace the Slack channel in the future.\\n\\nSo, let\'s [discuss](https://github.com/socketio/socket.io/discussions)!\\n\\n## Minor bumps\\n\\n- [[email protected]](https://github.com/socketio/socket.io-client/releases/tag/2.3.1) ([release notes](/blog/socket-io-2-3-1/))\\n  - [[email protected]](https://github.com/socketio/engine.io-parser/releases/tag/2.2.1) (included in `socket.io-client{% raw %}@{% endraw %}2.3.1`)\\n  - [[email protected]](https://github.com/socketio/engine.io-client/releases/tag/3.4.4) (included in `socket.io-client{% raw %}@{% endraw %}2.3.1`)\\n  - [[email protected]](https://github.com/socketio/socket.io-parser/releases/tag/3.3.1) (included in `socket.io-client{% raw %}@{% endraw %}2.3.1`)\\n\\n- [[email protected]](https://github.com/darrachequesne/socket.io-json-parser/releases/tag/2.1.1)\\n- [[email protected]](https://github.com/socketio/socket.io-msgpack-parser/releases/tag/2.2.1)\\n\\nMore information about how to use those custom parsers can be found [here](https://github.com/socketio/socket.io/tree/master/examples/custom-parsers).\\n\\n## Going forward\\n\\nAs announced at the bottom of the Engine.IO v4 [release notes](/blog/engine-io-4-release/#What\u2019s-next), I ([@darrachequesne](https://github.com/darrachequesne/)) am now dedicated full time to the project since the beginning of September. This wouldn\'t be possible without our [sponsors](https://opencollective.com/socketio/#section-contributors), so again, a big thanks to them!\\n\\n\\nStay safe!"},{"id":"/socket-io-2-3-1/","metadata":{"permalink":"/blog/socket-io-2-3-1/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2020-10-02-2.3.1.md","source":"@site/blog/2020-10-02-2.3.1.md","title":"Socket.IO client 2.3.1","description":"Hi everyone!","date":"2020-10-02T00:00:00.000Z","formattedDate":"October 2, 2020","tags":[],"readingTime":0.57,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO client 2.3.1","slug":"/socket-io-2-3-1/","authors":"darrachequesne"},"prevItem":{"title":"Monthly update #1","permalink":"/blog/monthly-update-1/"},"nextItem":{"title":"Engine.IO 4 Release","permalink":"/blog/engine-io-4-release/"}},"content":"Hi everyone!\\n\\nWe have published a minor version of the client: [2.3.1](https://github.com/socketio/socket.io-client/releases/tag/2.3.1)\\n\\n\x3c!--truncate--\x3e\\n\\nThe `debug` dependency has been reverted to `~3.1.0`, as the newer versions contains ES6 syntax which breaks in IE browsers.\\n\\nPlease note that this only applied to users that bundle the Socket.IO client in their application, with webpack for example, as the \\"official\\" bundles (in the dist/ folder) were already transpiled with babel.\\n\\nFor webpack users, you can also take a look at the [webpack-remove-debug](https://github.com/johngodley/webpack-remove-debug) plugin.\\n\\n### Bug Fixes\\n\\
1n* fix reconnection after opening socket asynchronously ([#1253](https://github.com/socketio/socket.io-client/issues/1253)) ([050108b](https://github.com/Automattic/socket.io-client/commit/050108b2281effda086b197cf174ee2e8e1aad79))\\n\\n\\nGet the latest client from the CDN:\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.1/socket.io.slim.js\\"><\/script>\\n```\\n\\nFor an explanation between the different bundles, please see [here](/docs/v2/client-installation/).\\n\\nStay safe!"},{"id":"/engine-io-4-release/","metadata":{"permalink":"/blog/engine-io-4-release/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2020-09-10-engine-io-4.md","source":"@site/blog/2020-09-10-engine-io-4.md","title":"Engine.IO 4 Release","description":"We are happy to announce the release of Engine.IO v4, the low-level engine that powers Socket.IO.","date":"2020-09-10T00:00:00.000Z","formattedDate":"September 10, 2020","tags":[],"readingTime":4.565,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Engine.IO 4 Release","slug":"/engine-io-4-release/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO client 2.3.1","permalink":"/blog/socket-io-2-3-1/"},"nextItem":{"title":"Socket.IO 2.0.1, 2.0.2 and 2.0.3","permalink":"/blog/socket-io-2-0-1-2-0-2-and-2-0-3/"}},"content":"We are happy to announce the release of Engine.IO v4, the low-level engine that powers Socket.IO.\\n\\n\x3c!--truncate--\x3e\\n\\n## Major breaking changes\\n\\n### Heartbeat mechanism reversal\\n\\nWe have received a lot of reports from users that experience random disconnects due to ping timeout, even though their Internet connection is up and the remote server is reachable. It should be noted that in that case the client reconnects right away, but still it was an annoying issue.\\n\\nAfter analysis, it seems to be caused by delayed timers on the client-side. Those timers are used in the ping-pong mechanism which helps to ensure the connection between the server and the client is still healthy. A delay on the client-side meant the client sent the ping packet too late, and the server considered that the connection was closed.\\n\\nThat\'s why the ping packets will now be sent by the server, and the client will respond with a pong packet.\\n\\n\\n### Packet encoding\\n\\nWe have also changed the way the data is encoded. It previously relied on the string length in Javascript, which meant it was harder to implement clients in other programming languages that do not share the same encoding (more details [here](https://mathiasbynens.be/notes/javascript-encoding)).\\n\\nTechnically speaking, it impacts the way an array of packets is encoded when using XHR polling (WebSocket is not affected, as each packet is sent in its own WebSocket frame).\\n\\n```js\\nsocket.send(\\"\u20ac\u20ac\\");\\nsocket.send(\\"\u0439\\");\\n\\n// v3 encoding output\\n\\"3:4\u20ac\u20ac2:4\u0439\\"\\n\\n// 3\\t\\t\\"4\u20ac\u20ac\\".length (the JS specific part, 6 bytes)\\n// :\\t\\tseparator\\n// 4\\t\\tthe \\"message\\" packet type\\n// \u20ac\u20ac\\t\\tthe content of the first packet\\n// 2\\t\\t\\"4\u0439\\".length (again, the JS specific part)\\n// :\\t\\tseparator\\n// 4\\t\\tthe \\"message\\" packet type\\n// \u0439\\t\\tthe content of the second packet\\n\\n// v4 encoding output\\n\\"4\u20ac\u20ac\\\\x1e4\u0439\\"\\n\\n// 4\\t\\tthe \\"message\\" packet type\\n// \u20ac\u20ac\\t\\tthe content of the first packet\\n// \\\\x1e\\t\\tseparator\\n// 4\\t\\tthe \\"message\\" packet type\\n// \u0439\\t\\tthe content of the second packet\\n```\\n\\nYou can find more details about the updates to the protocol [here](https://github.com/socketio/engine.io-protocol#difference-between-v3-and-v4).\\n\\n## Other changes\\n\\n### CORS handling\\n\\nWe now use the [cors](https://www.npmjs.com/package/cors) package to handle the [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) configuration. The `handlePreflightRequest` option was removed:\\n\\n```js\\nconst { Server } = require(\'engine.io\');\\n\\n// before\\nnew Server({\\n  handlePreflightRequest: (req, res) => {\\n    res.writeHead(200, {\\n      \\"Access-Control-Allow-Origin\\": \'https://example.com\',\\n      \\"Access-Control-Allow-Methods\\": \'GET\',\\n      \\"Access-Control-Allow-Headers\\": \'Authorization\',\\n      \\"Access-Control-Allow-Credentials\\": true\\n    });\\n    res.end();\\n  }\\n});
1\\n\\n// after\\nnew Server({\\n  cors: {\\n    origin: \\"https://example.com\\",\\n    methods: [\\"GET\\"],\\n    allowedHeaders: [\\"Authorization\\"],\\n    credentials: true\\n  }\\n});\\n```\\n\\nPlease see [here](https://github.com/expressjs/cors#configuration-options) for all available options.\\n\\n\\n### No cookie by default\\n\\nIn Engine.IO v3, the `io` cookie was sent by default. This cookie can be used to enable sticky-session, which is required when you have several servers (more information [here](/docs/v4/using-multiple-nodes/)).\\n\\nHowever, this cookie is not needed in some cases (i.e. single server deployment, sticky-session based on IP) so it must now be explicitly enabled:\\n\\n```js\\nconst { Server } = require(\'engine.io\');\\n\\n// before\\nnew Server({\\n  cookieName: \\"io\\",\\n  cookieHttpOnly: false,\\n  cookiePath: \\"/custom\\"\\n});\\n\\n// after\\nnew Server({\\n  cookie: {\\n    name: \\"test\\",\\n    httpOnly: false,\\n    path: \\"/custom\\"\\n  }\\n});\\n```\\n\\nAll other options (domain, maxAge, sameSite, ...) are now supported. Please see [here](https://github.com/jshttp/cookie/) for the complete list of options.\\n\\n\\n### The default value of maxHttpBufferSize was decreased\\n\\nThis option defines how many bytes or characters a message can be, before closing the connection. It was reduced from `100MB` to `1MB`.\\n\\n```js\\nconst { Server } = require(\'engine.io\');\\n\\nnew Server({\\n  maxHttpBufferSize: 1e8 // defaults to 1e6\\n});\\n```\\n\\n\\n### perMessageDeflate is now disabled by default\\n\\nThis option defines whether the WebSocket [permessage-deflate extension](https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19) is enabled or not. This feature, while useful in some cases, adds some extra memory overhead for each WebSocket connection, and could result in huge memory usage in production deployments. It is now disabled by default.\\n\\n```js\\nconst { Server } = require(\'engine.io\');\\n\\nnew Server({\\n  perMessageDeflate: true // defaults to false\\n});\\n```\\n\\n\\n### Support for Node.js 8 was dropped\\n\\nWe are dropping support for Node.js 8, which is now [End-of-Life](https://github.com/nodejs/Release). It will not be tested in the CI anymore, so please upgrade as soon as possible!\\n\\n\\n\\n## How to upgrade\\n\\nAs detailed in the [Major breaking changes](#Major-breaking-changes) section, this release contains several backward incompatible changes, and as such v3 clients will not be able to connect to a v4 server (and vice versa).\\n\\nIn order to upgrade a live production environment, you will need to have both a group of v3 servers and v4 servers in parallel, and route the traffic based on either:\\n\\n- the `EIO` query parameter\\n- the path (by using a different `path` for the v4 servers)\\n- or the domain if you use a different domain for the v4 servers\\n\\nSo that it shall be a seamless migration for your end users.\\n\\n\\n## What\'s next\\n\\nThis release will be included in Socket.IO v3 in the near future. We will publish a more detailed roadmap in the next blog post.\\n\\n\\nBesides, I ([@darrachequesne](https://github.com/darrachequesne/)) am glad to announce that I will be dedicated full time to the project for the next months. This is possible thanks to our awesome [sponsors](https://opencollective.com/socketio/#section-contributors).\\n\\nAgain, a big shout out to [Pia Mancini](https://twitter.com/piamancini) and all the team behind the [Open Collective](https://opencollective.com/) platform, which helps making Open Source Software sustainable in the long term.\\n\\n\\n## Let\'s discuss!\\n\\nThe project is now part of the beta of Github Discussions. Depending on the feedback of the community, it might replace the Slack channel in the future.\\n\\nIf you have any question about the release, let\'s discuss about it [here](https://github.com/socketio/socket.io/discussions/3644).\\n\\n\\n\\nStay safe!"},{"id":"/socket-io-2-0-1-2-0-2-and-2-0-3/","metadata":{"permalink":"/blog/socket-io-2-0-1-2-0-2-and-2-0-3/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2017-06-24-2.0.x.md","source":"@site/blog/2017-06-24-2.0.x.md","title":"Socket.IO 2.0.1, 2.0.2 and 2.0.3","description":"We published three minor releases right after 2.0.0, so please be sure to use the latest version!","date":"2017-06-24T00:00:00.000Z","formattedDate":"June 24, 2017","tags":[],"readingTime":0.34,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 2.0.1, 2.0.2 and 2.0.3","slug":"/socket-io-2-0-1-2-0-2-and-2-0-3/","authors":"darrachequesne"},"prevItem":{"title":"Engine.IO 4 Release","permalink":"/blog/engine-io-4-release/"},"nextItem":{"title":"Socket.IO is on Open Collective","permalink":"/blog/socket-io-is-on-open-collective/"}},"content":"We published three minor releases right after `2.0.0`, so please be sure to use the latest version!\\n\\n\x3c!--truncate--\x3e\\n\\nIncluding:\\n\\n- A fix for a race condition within middleware: [Issue #2935](https://github.com/socketio/socket.io/issues/2935)\\n\\n- A fix for a potential race condition when emitting to a room: [Issue #2962](https://github.com/socketio/socket.io/issues/2962)\\n\\n- A fix for the *query* option in the client: [Issue #1086](https://github.com/socketio/socket.io-client/issues/1086)\\n\\
1nGet the latest client from the CDN:\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js\\"><\/script>\\n```"},{"id":"/socket-io-is-on-open-collective/","metadata":{"permalink":"/blog/socket-io-is-on-open-collective/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2017-05-15-open-collective.md","source":"@site/blog/2017-05-15-open-collective.md","title":"Socket.IO is on Open Collective","description":"Open Collective provides a transparent, sustainable, and secure way for people to support and sponsor open source projects. We are joining other great projects (you may have heard about MochaJS, GulpJS or webpack, among lots of other awesome projects) in the quest to ensure the project\'s sustainability.","date":"2017-05-15T00:00:00.000Z","formattedDate":"May 15, 2017","tags":[],"readingTime":1.435,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO is on Open Collective","slug":"/socket-io-is-on-open-collective/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO 2.0.1, 2.0.2 and 2.0.3","permalink":"/blog/socket-io-2-0-1-2-0-2-and-2-0-3/"},"nextItem":{"title":"Socket.IO 2.0.0","permalink":"/blog/socket-io-2-0-0/"}},"content":"<img src=\\"/images/opencollective.png\\"/>\\n\\nOpen Collective provides a transparent, sustainable, and secure way for people to support and sponsor <a href=\\"https://opencollective.com/opensource\\">open source projects</a>. We are joining other great projects (you may have heard about <a href=\\"https://opencollective.com/mochajs\\">MochaJS</a>, <a href=\\"https://opencollective.com/gulpjs\\">GulpJS</a> or <a href=\\"https://opencollective.com/webpack\\">webpack</a>, among <a href=\\"https://opencollective.com/discover\\">lots</a> of other awesome projects) in the quest to ensure the project\'s sustainability.\\n\\n\x3c!--truncate--\x3e\\n\\n## What is an Open Collective?\\n\\nFrom their website:\\n\\n*An Open Collective is a group of people with a shared mission that operates in full transparency.*\\n\\nThat allows both individuals and companies to sponsor our mission at Socket.IO (with potential tax benefits).\\n\\n## What would Socket.IO do with my sponsorship?\\n\\nThat will enable the core contributors to spend more time assuring the maintenance of the project. That includes:\\n\\n- triaging issues and pull requests\\n\\n- answering questions on <a href=\\"https://slackin-socketio.now.sh/\\">Slack</a> and <a href=\\"http://stackoverflow.com/questions/tagged/socket.io\\">Stackoverflow</a>
1 (which have been somewhat neglected recently)\\n\\n- updating the documentation (I think a lot has been done recently, but there is still room for improvement!)\\n\\nPersonally I would like to be able to devote a few days a month to the project (I mean a whole day of work, not a few hours taken here and there, usually late in the evening).\\n\\nThe goals in the near future:\\n\\n- keep the 2.0 version as stable as possible\\n- provide a complete documentation\\n- add more examples, besides the classic chat\\n\\n## How can I help?\\n\\nTo become a sponsor or backer, visit our <a href=\\"https://opencollective.com/socketio\\">open collective page</a> and follow the instructions for becoming a part of our collective. Please also take the time to explore the other awesome collectives that people are supporting.\\n\\nAnd finally, a big thanks to <a href=\\"https://twitter.com/piamancini\\">Pia Mancini</a> and her partners for making this possible."},{"id":"/socket-io-2-0-0/","metadata":{"permalink":"/blog/socket-io-2-0-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2017-05-13-2-0-0.md","source":"@site/blog/2017-05-13-2-0-0.md","title":"Socket.IO 2.0.0","description":"Socket.IO 2.0.0 is finally here!","date":"2017-05-13T00:00:00.000Z","formattedDate":"May 13, 2017","tags":[],"readingTime":0.74,"hasTruncateMarker":true,"authors":[{"name":"Damien Arrachequesne","title":"Maintainer of Socket.IO","url":"https://github.com/darrachequesne","imageURL":"https://github.com/darrachequesne.png","key":"darrachequesne"}],"frontMatter":{"title":"Socket.IO 2.0.0","slug":"/socket-io-2-0-0/","authors":"darrachequesne"},"prevItem":{"title":"Socket.IO is on Open Collective","permalink":"/blog/socket-io-is-on-open-collective/"},"nextItem":{"title":"Socket.IO 1.4.5","permalink":"/blog/socket-io-1-4-5/"}},"content":"Socket.IO 2.0.0 is finally here!\\n\\n\x3c!--truncate--\x3e\\n\\nThis major release brings several performance improvements:\\n\\n- [uws](https://github.com/uWebSockets/uWebSockets) is now the default Websocket engine. It should bring significant improvement in performance (particularly in terms of memory consumption) ([release note of Engine.IO](https://github.com/socketio/engine.io/releases/tag/2.0.0))\\n\\n- the Engine.IO and Socket.IO handshake packets were merged, reducing the number of roundtrips necessary to establish a connection. ([#2833](https://github.com/socketio/socket.io/pull/2833))\\n\\n- it is now possible to provide a custom parser according to the needs of your application ([#2829](https://github.com/socketio/socket.io/pull/2829)). Please take a look at the [example](https://github.com/socketio/socket.io/tree/master/examples/custom-parsers) for more information.\\n\\nPlease note that this release is not backward-compatible, due to:\\n\\n- a breaking change related to utf-8 encoding in [engine.io-parser](https://github.com/socketio/engine.io-parser/pull/81)\\n\\n- an update to make the socket id on the client match the id on the server-side ([#1058](https://github.com/socketio/socket.io-client/pull/1058))\\n\\nRelated packages were updated accordingly:\\n\\n- socket.io-redis version [5.x](https://github.com/socketio/socket.io-redis/releases/tag/5.0.0)\\n\\n- socket.io-emitter version [3.x](https://github.com/socketio/socket.io-emitter/releases/tag/3.0.0)\\n\\nGet the latest client from the CDN:\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.1/socket.io.js\\"><\/script>\\n```"},{"id":"/socket-io-1-4-5/","metadata":{"permalink":"/blog/socket-io-1-4-5/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2016-01-27-1.4.5.md","source":"@site/blog/2016-01-27-1.4.5.md","title":"Socket.IO 1.4.5","description":"We just published some quick fixes!","date":"2016-01-27T00:00:00.000Z","formattedDate":"January 27, 2016","tags":[],"readingTime":0.185,"hasTruncateMarker":true,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}
1],"frontMatter":{"title":"Socket.IO 1.4.5","slug":"/socket-io-1-4-5/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 2.0.0","permalink":"/blog/socket-io-2-0-0/"},"nextItem":{"title":"Socket.IO 1.4.4","permalink":"/blog/socket-io-1-4-4/"}},"content":"We just published some quick fixes!\\n\\n\x3c!--truncate--\x3e\\n\\n- Fixed `socket.io-client` usage with [NativeScript](https://www.nativescript.org/).\\n- Fixed graceful close of the attached http `Server` of `socket.io` and `engine.io`.\\n\\nGet the latest client from the CDN:\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-1-4-4/","metadata":{"permalink":"/blog/socket-io-1-4-4/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2016-01-11-1.4.4.md","source":"@site/blog/2016-01-11-1.4.4.md","title":"Socket.IO 1.4.4","description":"We just published two fixes for socket.io-client:","date":"2016-01-11T00:00:00.000Z","formattedDate":"January 11, 2016","tags":[],"readingTime":0.295,"hasTruncateMarker":true,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.4.4","slug":"/socket-io-1-4-4/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.4.5","permalink":"/blog/socket-io-1-4-5/"},"nextItem":{"title":"Socket.IO 1.4.1, 1.4.2 and 1.4.3","permalink":"/blog/socket-io-1-4-1-1-4-2-and-1-4-3/"}},"content":"We just published two fixes for `socket.io-client`:\\n\\n- Building with `browserify` or `webpack` is now completely straightforward. No need to `exclude/ignore` or `noParse/externals` the `ws` module.\\n\\n- Improved the JSONP transport when `socket.io-client` or `engine.io-client` are lazily evaluated or the `<script>` tag that included them gets removed.\\n\\n\x3c!--truncate--\x3e\\n\\nGet the latest client from the CDN:\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.4/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-1-4-1-1-4-2-and-1-4-3/","metadata":{"permalink":"/blog/socket-io-1-4-1-1-4-2-and-1-4-3/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2016-01-08-1.4.x.md","source":"@site/blog/2016-01-08-1.4.x.md","title":"Socket.IO 1.4.1, 1.4.2 and 1.4.3","description":"We published three minor releases right after 1.4.0 addressing build issues in different environments.","date":"2016-01-08T00:00:00.000Z","formattedDate":"January 8, 2016","tags":[],"readingTime":0.24,"hasTruncateMarker":true,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.4.1, 1.4.2 and 1.4.3","slug":"/socket-io-1-4-1-1-4-2-and-1-4-3/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.4.4","permalink":"/blog/socket-io-1-4-4/"},"nextItem":{"title":"Socket.IO 1.4.0","permalink":"/blog/socket-io-1-4-0/"}},"content":"We published three minor releases right after `1.4.0` addressing build issues in different environments.\\n\\n\x3c!--truncate--\x3e\\n\\n- Socket.IO-client now includes the latest version of <a href=\\"https://github.com/socketio/engine.io-client\\">engine.io-client</a>\\n\\n- Fixed an issue that was preventing bundling with <a href=\\"https://webpack.github.io/\\">webpack</a>.\\n\\n- Socket.IO now adds support for <a href=\\"https://www.nativescript.org/\\">NativeScript</a>!\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.3/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-1-4-0/","metadata":{"permalink":"/blog/socket-io-1-4-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2016-01-06-1.4.0.md","source":"@site/blog/2016-01-06-1.4.0.md","title":"Socket.IO 1.4.0","description":"Socket.IO 1.4.0 ship with new features like automatic compression for XHR and WebSockets, lots of bug fixes and significant performance and memory improvements.","date":"2016-01-06T00:00:00.000Z","formattedDate":"January 6, 2016","tags":[],"readingTime":2.975,"hasTruncateMarker":true,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.4.0","slug":"/socket-io-1-4-0/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.4.1, 1.4.2 and 1.4.3","permalink":"/blog/socket-io-1-4-1-1-4-2-and-1-4-3/"},"nextItem":{"title":"Socket.IO 1.3.7","permalink":"/blog/socket-io-1-3-7/"}},"content":"Socket.IO 1.4.0 ship with new features like **automatic compression** for XHR and WebSockets, lots of bug fixes and significant performance and memory improvements.\\n\\n\x3c!--truncate--\x3e\\n\\nCompression is enabled by default, as it\u2019s highly beneficial for most application payloads. The following example shows the savings for a realtime stream of tweets.\\n\\n<div id=\\"tweets-compression-demo\\"></div>\\n\\nThe compression gains will vary by transport. For example, WebSocket defaults to a window size of 32kb when **DEFLATE** compression is enabled. Repeated occurrences of strings within that window will be compressed.\\nThe following demo (inspired by Julia Evans <a href=\\"http://jvns.ca/blog/2013/10/24/day-16-gzip-plus-poetry-equals-awesome/\\">work</a>) will highlight what the LZ77 algorithm de-duplicates from the traffic sent by the Twitter stream that matches <em>javascript</em>.\\n\\n<div id=\\"lz77-compression-demo\\"></div>\\n\\n<p style={{ fontSize: \'10px\', color: \'#999\' }}>How this demo works: we re-implemented a part of <a style={{ color: \'#888\' }} href=\\"https://github.com/socketio/lz77-compression-demo/blob/master/public/lz77-analyzer.js\\">LZ77 in JavaScript</a>. A <a style={{ color: \'#888\' }} href=\\"https://github.com/socketio/lz77-compression-demo/blob/master/public/component.js#L67\\">React component</a> then renders the compressed strings.</p>\\n\\nThe longer the string, the darker the shade of yellow displayed.\\n\\nIn addition to this default behavior, we\u2019ve introduced the capability to perform selective per-message compression, by introducing the `compress` flag when emitting an event.\\n\\n```js\\nsocket.compress(true).emit(\u2018hi\u2019, { some: \u2018data\u2019 });\\n```\\n\\nTo configure the defaults, we\u2019ve introduced the following two options that you can pass to socket.io (and engine.io) when starting the server:\\
1n\\n- `perMessageDeflate` \u2013 options to customize WebSocket compression (<a href=\\"https://github.com/websockets/ws/blob/master/doc/ws.md#optionspermessagedeflate\\" target=\\"_blank\\">see here</a>) or `true` for defaults (`true`).\\n\\n- `httpCompression` \u2013 options to customize compression for HTTP polling transports or `true` for defaults (`true`)\\n\\nThe memory overhead when compression is enabled is not inexistent, however. Make sure to account for a 300kb~ overhead per connection in terms of memory allocation. <a href=\\"https://www.igvita.com/2013/11/27/configuring-and-optimizing-websocket-compression/\\">Read here</a> about the parameters you can customize to change how much memory is allocated and how aggressively data is compressed.\\n\\n\\nThe following improvements have been made to the **<a href=\\"https://github.com/socketio/socket.io\\">server</a>**:\\n\\n- Assume 443 port when passing `https://` to the `origins` parameter \u2013 Evan Lucas\\n- Improve detection of binary data inside events (in the `has-binary` module) \u2013 Gunther Brunner\\n- Warn about missing `error` event handlers on sockets to prevent silent hard-to-debug situations\\n- Allow a custom function for the `allowRequest` function for origins verification\\n- Fixes for \u201cuse strict\u201d environments \u2013 Naoyuki Kanezawa\\n- Prevent users calling the ack function multiple times \u2013 Kevin Jose Martin\\n- Fixed potential memory leaks with open sockets when upgrade fails \u2013 Naoyuki Kanezawa\\n- Fix lingering requests when a polling error occurs \u2013 Naoyuki Kanezawa\\n- Drastically more memory efficient when keeping track of clients \u2013 Damien Arrachequesne\\n- Drastically more memory efficient when keeping track of rooms \u2013 J\xe9r\xe9my Lal\\n- Trigger callback if the client is already in the given room when `join` is called \u2013 Damien Arrachequesne\\n- Minor parser fixes and performance improvements.\\n\\nThe following improvements have been made to the **<a href=\\"https://github.com/socketio/socket.io-client\\">client</a>**:\\n\\n- Fix for specifying custom ports when connecting\\n- 2 or more connections to the same namespace now create new sockets, instead of reusing a single one.\\n- Added new reserved `ping` and `pong` events when a heartbeat is emitted and received.\\n- Add support for environments that extend Object.prototype \u2013 Damien Arrachequesne\\n- Fixes for \u201cuse strict\u201d environments \u2013 Naoyuki Kanezawa\\n- Added an `extraHeaders` feature for custom headers in HTTP transports (non-WebSocket)\\n- Fix handling of disconnection while in the `opening` state.\\n- Improved error handling for unmatched acknowledgements.\\n- Parser fixes and improvements.\\n\\nWe\'ve also released **<a href=\\"https://github.com/socketio/socket.io-redis\\">socket.io-redis</a>** `0.2.0` with significant performance improvements.\\n\\nSpecial thanks to <em>Damien Arrachequesne</em>, <em>Naoyuki Kanezawa</em> and <em>J\xe9r\xe9my Lal</em> for their amazing and continued contributions that made this release possible."},{"id":"/socket-io-1-3-7/","metadata":{"permalink":"/blog/socket-io-1-3-7/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-09-21-1.3.7.md","source":"@site/blog/2015-09-21-1.3.7.md","title":"Socket.IO 1.3.7","description":"Socket.IO 1.3.7 includes support for io.js and Node.JS 4.0.0.","date":"2015-09-21T00:00:00.000Z","formattedDate":"September 21, 2015","tags":[],"readingTime":0.065,"hasTruncateMarker":false,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.3.7","slug":"/socket-io-1-3-7/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.4.0","permalink":"/blog/socket-io-1-4-0/"},"nextItem":{"title":"Socket.IO 1.3.6","permalink":"/blog/socket-io-1-3-6/"}},"content":"Socket.IO **1.3.7** includes support for io.js and Node.JS 4.0.0.\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.7/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-1-3-6/","metadata":{"permalink":"/blog/socket-io-1-3-6/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-07-15-1.3.6.md","source":"@site/blog/2015-07-15-1.3.6.md","title":"Socket.IO 1.3.6","de
1scription":"Socket.IO 1.3.6 addresses a build issue with the ws module on Windows.","date":"2015-07-15T00:00:00.000Z","formattedDate":"July 15, 2015","tags":[],"readingTime":0.08,"hasTruncateMarker":false,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.3.6","slug":"/socket-io-1-3-6/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.3.7","permalink":"/blog/socket-io-1-3-7/"},"nextItem":{"title":"Socket.IO P2P","permalink":"/blog/socket-io-p2p/"}},"content":"Socket.IO **1.3.6** addresses a build issue with the `ws` module on Windows.\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-p2p/","metadata":{"permalink":"/blog/socket-io-p2p/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-07-14-p2p.md","source":"@site/blog/2015-07-14-p2p.md","title":"Socket.IO P2P","description":"Today were very happy to introduce Socket.IO P2P, the easiest way to establish a bidirectional events channel between two peers with a server fallback to provide maximum reliability.","date":"2015-07-14T00:00:00.000Z","formattedDate":"July 14, 2015","tags":[],"readingTime":3.04,"hasTruncateMarker":true,"authors":[{"name":"Tom Cartwright","title":"Maintainer of the Socket.IO P2P project","url":"https://twitter.com/tomcartwrightuk","image_url":"https://github.com/tomcartwrightuk.png","imageURL":"https://github.com/tomcartwrightuk.png"}],"frontMatter":{"title":"Socket.IO P2P","slug":"/socket-io-p2p/","authors":[{"name":"Tom Cartwright","title":"Maintainer of the Socket.IO P2P project","url":"https://twitter.com/tomcartwrightuk","image_url":"https://github.com/tomcartwrightuk.png","imageURL":"https://github.com/tomcartwrightuk.png"}]},"prevItem":{"title":"Socket.IO 1.3.6","permalink":"/blog/socket-io-1-3-6/"},"nextItem":{"title":"Socket.IO C++","permalink":"/blog/socket-io-cpp/"}},"content":"Today were very happy to introduce Socket.IO P2P, the easiest way to establish **a bidirectional events channel between two peers** with a server fallback to provide maximum reliability.\\n\\n\x3c!--truncate--\x3e\\n\\nLets look at the API and build a little chat application. Or check out <a href=\\"https://github.com/socketio/socket.io-p2p\\">the repository</a> directly!\\n\\n<p style={{ textAlign: \'center\', padding: \'20px 0\' }}>\\n  <img src=\\"https://cldup.com/95U80xyuHq.svg\\"/>\\n</p>\\n\\n\\n**Socket.IO <span style={{ color: \'#F04\' }}>P2P</span>** provides an **easy and reliable** way to setup a <a href=\\"http://www.webrtc.org/\\">WebRTC</a> connection between peers and communicate using the <a href=\\"https://github.com/socketio/socket.io-protocol\\">socket.io-protocol</a>.\\n\\nSocket.IO is used to transport <a href=\\"http://www.html5rocks.com/en/tutorials/webrtc/infrastructure/#what-is-signaling\\">signaling data</a> and as a <em>fallback</em> for clients where the WebRTC `PeerConnection` is not supported. Adding a simple piece of middleware to your socket.io setup enables this \u2013 no need to hand roll your own signaling exchange or set up, deploy and scale new servers.\\n\\n## Usage\\n\\nIt only takes a few lines of code to set up the server and client.\\n\\nServer:\\n\\n```js\\nvar io = require(\'socket.io\')(server);\\nvar p2p = require(\'socket.io-p2p-server\').Server;\\nio.use(p2p);\\n```\\n\\nClient:\\n\\n```js\\nvar P2P = require(\'socket.io-p2p\');\\nvar io = require(\'socket.io-client\');\\nvar socket = io();\\nvar p2p = new P2P(socket);\\np2p.on(\'peer-msg\', function (data) {\\n  console.log(\'From a peer %s\', data);\\n});\\n```\\n\\nThere are various options for the advanced user. Once signaling data has been exchanged an `upgrade` event is triggered and an optional callback is called.\\n\\n```js\\nvar opts = { numClients: 10 }; // connect up to 10 clients at a time\\nvar p2p = new P2P(socket, opts, function(){\\n  console.log(\'We all speak WebRTC now\');\\n});\\n```\\n\\n## The Chat example\\n\\nWe will build a simple chat application, as our tradition dictates, but with P2P capabilities! In this application:\\n\\n- Clients can send text messages to each other. Messages display in a timeline\\n- Clients connect to each other over socket.io and initially send messages via the server\\n- Clients can choose to **go private** \u2013 switching the transport to WebRTC\\n- All clients connected to the server can connect via WebRTC up to a maximum of 10 clients\\n\\nAll code from this example is included in the <a href=\\"https://github.com/socketio/socket.io-p2p/tree/master/examples/chat\\">main repository</a>.\\n\\nWe first setup the client with `autoUpgrade` set to false so that clients can upgrade the connection themselves. Set `numClients` to `10` to allow up to 10 clients to connect with each other.\\n\\n```js\\nvar opts = {autoUpgrade: false, numClients: 10};\\nvar p2psocket = new P2P(socket, opts)\\n```\\n\\nSetup the event listeners:\\n\\n```js\\np2psocket.on(\'peer-msg\', function(data) {\\n  // append message to list\\n});\\n\\np2psocket.on(\'go-private\', function () {\\n  p2psocket.upgrade(); // upgrade to peerConnection\\n});\\n```\\n\\nIn this example, we want any clients connecting to the server to exchange signaling data with each other. We can use the server component as a simple middleware. Clients will connect on the root namespace.\\n\\nIf we wanted clients to exchange signalling data in rooms, rather than on a whole namespace, we could use the server module upon connection <a href=\\"https://github.com/tomcartwrightuk/p2p-snake/blob/master/server.js\\">like this</a>
1.\\n\\n```js\\nvar server = require(\'http\').createServer();\\nvar p2pserver = require(\'socket.io-p2p-server\').Server\\nvar io = require(\'socket.io\')(server);\\nserver.listen(3030)\\nio.use(p2pserver);\\n```\\n\\nWe then setup listeners to pass messages between clients and to broadcast the `go-private` event.\\n\\n```js\\nio.on(\'connection\', function(socket) {\\n  socket.on(\'peer-msg\', function(data) {\\n    console.log(\'Message from peer: %s\', data);\\n    socket.broadcast.emit(\'peer-msg\', data);\\n  })\\n\\n  socket.on(\'go-private\', function(data) {\\n    socket.broadcast.emit(\'go-private\', data);\\n  });\\n});\\n```\\n\\nThats all you need: add a little markup we are off! Heres the demo application in action:\\n\\n<a href=\\"/images/P2PChatExampleRedo2.gif\\"><img src=\\"/images/P2PChatExampleRedo2.gif\\" alt=\\"P2PChatExampleRedo2\\" width=\\"854\\" height=\\"317\\" className=\\"alignnone size-full wp-image-921\\"/></a>\\n\\nThanks to Guillermo Rauch (<a href=\\"https://twitter.com/rauchg\\">@rauchg</a>) for the advice, testing and patience, Harrison Harnisch (<a href=\\"https://github.com/hharnisc\\">@hharnisc</a>) for bug fixes and to Feross Aboukhadijeh (<a href=\\"https://github.com/feross\\">@feross</a>) for providing the underlying WebRTC abstraction <a href=\\"https://github.com/feross/simple-peer\\">simple-peer</a>.\\n\\nPull requests, issues, comments and general rantings are all welcome over at the GitHub <a href=\\"https://github.com/socketio/socket.io-p2p\\">repo</a>."},{"id":"/socket-io-cpp/","metadata":{"permalink":"/blog/socket-io-cpp/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-04-13-socket-io-cpp.md","source":"@site/blog/2015-04-13-socket-io-cpp.md","title":"Socket.IO C++","description":"I\'m really proud to announce the first release of the Socket.IO C++ Client on GitHub!","date":"2015-04-13T00:00:00.000Z","formattedDate":"April 13, 2015","tags":[],"readingTime":5.98,"hasTruncateMarker":true,"authors":[{"name":"Melo Yao","title":"Maintainer of the C++ client","url":"https://twitter.com/melode111","image_url":"https://github.com/melode11.png","imageURL":"https://github.com/melode11.png"}],"frontMatter":{"title":"Socket.IO C++","slug":"/socket-io-cpp/","authors":[{"name":"Melo Yao","title":"Maintainer of the C++ client","url":"https://twitter.com/melode111","image_url":"https://github.com/melode11.png","imageURL":"https://github.com/melode11.png"}]},"prevItem":{"title":"Socket.IO P2P","permalink":"/blog/socket-io-p2p/"},"nextItem":{"title":"Socket.IO on iOS","permalink":"/blog/socket-io-on-ios/"}},"content":"I\'m really proud to announce the first release of the <a href=\\"https://github.com/socketio/socket.io-client-cpp\\">Socket.IO C++ Client</a> on GitHub!\\n\\n\x3c!--truncate--\x3e\\n\\nBased on <a href=\\"http://www.boost.org/\\">Boost</a> and <a href=\\"https://github.com/zaphoyd/websocketpp\\">WebSocket++</a>, this full-featured Socket.IO 1.0 client has the fundamental advantage of working on **multiple platforms**. Check out the directory of <a href=\\"https://github.com/socketio/socket.io-client-cpp/tree/master/examples\\">examples</a>. It contains examples of iOS, QT, and CLI chat clients!\\n\\nTo learn how to use this client, I put together a QT chat example that communicates using a <a href=\\"https://github.com/Automattic/socket.io/tree/master/examples/chat\\">Socket.IO Node.JS chat server</a>. Keep reading for step-by-step instructions.\\n\\n<p style={{ \'text-align\': \'center\' }}>\\n<img src=\\"https://cldup.com/98tHyoJJE7.gif\\" />\\n</p>\\n\\n## Introduction\\n\\nIf you\u2019d like to follow along, begin by cloning the <a href=\\"https://github.com/socketio/socket.io-client-cpp\\">socket.io-client-cpp</a> repository using the following:\\n\\n```bash\\ngit clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git\\n```\\n\\nThe app includes the following features:\\n\\n- Send messages to all users joining the room.\\n- Receive a notification when users join or leave the room.\\n- Receive notifications when a user starts typing a message.\\n\\nBefore you get started, visit the <a href=\\"http://www.qt.io/download-open-source/#section-2\\">QT community</a> to download and install QT.\\n\\n## Creating a QT GUI Application\\n\\nLaunch the QT Creator.\\n\\nOn the welcome page, select `New Project`, then create a `QT Widget Application.` Name it `SioChatDemo.`\\n\\nThe project structure should look like this:\\n\\n```\\nSioChatDemo\\n    |__ SioChatDemo.pro\\n    |__Headers\\n    |   |__mainwindow.h\\n    |__Sources\\n    |   |__main.cpp\\n    |   |__mainwindow.cpp\\n    |__Forms\\n        |__mainwindow.ui\\n```\\n\\n## Importing an SioClient\\n\\nLets copy the SioClient into the QT project under the subfolder `sioclient.`\\n\\nEdit `SioChatDemo.pro` to configure paths and compile options by simply adding:\\n\\n```bash\\nSOURCES += ./sioclient/src/sio_client.cpp\\n           ./sioclient/src/sio_packet.cpp\\n\\nHEADERS  += ./sioclient/src/sio_client.h\\n            ./sioclient/src/sio_message.h\\n\\nINCLUDEPATH += $$PWD/sioclient/lib/rapidjson/include\\nINCLUDEPATH += $$PWD/sioclient/lib/websocketpp\\n```\\n\\nAdd two additional compile options:\\n\\n```bash\\nCONFIG+=no_keywords\\nCONFIG+=c++11\\n```\\n\\nThe `no_keywords` flag prevents `qmake` from treating some function names as `emit` as the keyword for the signal-slot mechanism.\\n\\nUse `c++11` to ask for C++11 support.\\n\\n## Importing Boost\\n\\nWe now have our boost `headers` and a fat boost `static lib` named `libboost.a`(non-win32) or `boost.lib`(win32).\\n\\nTo import them, we need to edit `SioChatDemo.pro` again by adding a header including the following:\\n\\n```bash\\nINCLUDEPATH += `our boost headers folder`\\n```\\n\\nLinker options:\\n\\n```bash\\nwin32:CONFIG(release, debug|release): LIBS += -L`our Win32 boost static lib folder` -lboost\\nelse:win32:CONFIG(
1debug, debug|release): LIBS += -L`our Win32 boost static lib folder` -lboost\\nelse:unix: LIBS += -L`our osx boost static lib folder` -lboost\\n```\\n\\n## Create the Main Window UI\\n\\nCreate a simple UI by dragging and dropping a widget from the widget box on the left-hand side.\\n\\n<p style={{ \'text-align\': \'center\' }}>\\n<img src=\\"https://cldup.com/RI98CYpYL5.png\\" />\\n</p>\\n\\nIt contains the following:\\n\\n- A `QLineEdit` at the top to input a nickname: `nickNameEdit`\\n- A `QPushButton` at the top right for login: `loginBtn`\\n- A `QListWidget` in the center for showing messages: `listView`\\n- A `QLineEdit` at the bottom for typing messages: `messageEdit`\\n- A `QPushButton` at the bottom right for sending messages: `sendBtn`\\n\\n## Add Slots in the Main Window\\n\\nThe following slots need to be added in the `mainwindow` class to handle UI events:\\n\\n- Click \u2018Login\u2019 button\\n- Click \u2018Send Message\u2019 button\\n- Text change in message editing (to show typing status)\\n- Return message editing (for sending responses)\\n\\nInsert the following code into the `MainWindow` class in `mainwindow.h`:\\n\\n```cpp\\npublic Q_SLOTS:\\n    void SendBtnClicked();\\n    void TypingChanged();\\n    void LoginClicked();\\n    void OnMessageReturn();\\n```\\n\\n## Connect the UI Event Signal and Slots\\n\\nOpen `mainwindow.ui` in the design mode. Switch to the `signals/slots` mode using `Menu->Edit->Edit Signals/Slots`.\\n\\nClick and hold the widget and drag it to the window (the cursor will become an electrical ground symbol) to open the connection editor.\\n\\nIn the connection editor, edit the main window slots on the right side. Add the slot function names added in `mainwindow.h` before.\\n\\nThen we can connect the event signal to the widget with our own slots. The result should look like this:\\n\\n<p style={{ \'text-align\': \'center\' }}>\\n<img src=\\"https://cldup.com/Vsb-UXG3FC.jpg\\" />\\n</p>\\n\\n## Adding UI Refresh Signals/Slots\\n\\nThe `sio::client` callbacks are not in the UI thread. However, the UI must be updated with those callbacks, so we need a signal for the non-UI thread to request the `slots` functions in the UI thread. To signal that `QListWidgetItem` has been added, insert the following:\\n\\n```cpp\\n// in mainwindow.h\\nQ_SIGNALS:\\n    void RequestAddListItem(QListWidgetItem *item);\\nprivate Q_SLOTS:\\n    void AddListItem(QListWidgetItem *item);\\n```\\n\\n```cpp\\n//In mainwindow.cpp\\nvoid MainWindow::AddListItem(QListWidgetItem* item)\\n{\\n    this->findChild<QListWidget*>(\\"listView\\")->addItem(item);\\n}\\n```\\n\\nThen connect them in the `MainWindow` constructor.\\n\\n```cpp\\nconnect(this,SIGNAL(RequestAddListItem(QListWidgetItem*)),this,SLOT(AddListItem(QListWidgetItem*)));\\n```\\n\\n## Setting up the Socket\\n\\nFor single-window applications, simply let `MainWindow` class hold the `sio::client` object by declaring a `unique_ptr` member of the `sio::client` and several event handling functions in `mainwindow.h`.\\n\\n```cpp\\nprivate:\\n    void OnNewMessage(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);\\n    void OnUserJoined(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);\\n    void OnUserLeft(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);\\n    void OnTyping(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);\\n    void OnStopTyping(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);\\n    void OnLogin(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp);\\n    void OnConnected();\\n    void OnClosed(client::close_reason const& reason);\\n    void OnFailed();\\n\\n    std::unique_ptr<client> _io;\\n```\\n\\nInitialize `sio::client` and setup event bindings for the default `socket` in the `MainWindow` constructor.\\n\\nWe also need to handle connectivity and disconnect events.\\n\\nAdd the following to the `MainWindow` constructor:\\n\\n```cpp\\nM
1ainWindow::MainWindow(QWidget *parent) :\\n    QMainWindow(parent),\\n    ui(new Ui::MainWindow),\\n    _io(new client())\\n{\\n    ui->setupUi(this);\\n    using std::placeholders::_1;\\n    using std::placeholders::_2;\\n    using std::placeholders::_3;\\n    using std::placeholders::_4;\\n    socket::ptr sock = _io->socket();\\n    sock->on(\\"new message\\",std::bind(&MainWindow::OnNewMessage,this,_1,_2,_3,_4));\\n    sock->on(\\"user joined\\",std::bind(&MainWindow::OnUserJoined,this,_1,_2,_3,_4));\\n    sock->on(\\"user left\\",std::bind(&MainWindow::OnUserLeft,this,_1,_2,_3,_4));\\n    sock->on(\\"typing\\",std::bind(&MainWindow::OnTyping,this,_1,_2,_3,_4));\\n    sock->on(\\"stop typing\\",std::bind(&MainWindow::OnStopTyping,this,_1,_2,_3,_4));\\n    sock->on(\\"login\\",std::bind(&MainWindow::OnLogin,this,_1,_2,_3,_4));\\n    //default socket opened, also we have \\"set_open_listener\\" for monitoring physical connection opened.\\n    _io->set_socket_open_listener(std::bind(&MainWindow::OnConnected,this,std::placeholders::_1));\\n    //physical connection closed or drop.\\n    _io->set_close_listener(std::bind(&MainWindow::OnClosed,this,_1));\\n    //physical connection fail to establish.\\n    _io->set_fail_listener(std::bind(&MainWindow::OnFailed,this));\\n    connect(this,SIGNAL(RequestAddListItem(QListWidgetItem*)),this,SLOT(AddListItem(QListWidgetItem*)));\\n}\\n```\\n\\n## Managing Connection State\\n\\nWe have several connection listeners for connection events.\\n\\nFirst, we want to send a login message when were connected; we get the default `socket` from the `client` to do that.\\n\\n```cpp\\nvoid MainWindow::OnConnected()\\n{\\n    QByteArray bytes = m_name.toUtf8();\\n    std::string nickName(bytes.data(),bytes.length());\\n    _io->socket()->emit(\\"add user\\", nickName);\\n}\\n```\\n\\nIf the connection closes or fails, we need to restore the UI before we connect.\\n\\n````cpp\\nvoid MainWindow::OnClosed(client::close_reason const& reason)\\n{\\n    //restore UI to pre-login state\\n}\\n\\nvoid MainWindow::OnFailed()\\n{\\n    //restore UI to pre-login state\\n}\\n```\\n\\nIf we exit the `MainWindow`, we need to clear the event bindings and listeners.\\n\\nThe `sio::client` object will be destroyed using `unique_ptr`.\\n\\n```cpp\\nM
1ainWindow::~MainWindow()\\n{\\n    _io->socket()->off_all();\\n    _io->socket()->off_error();\\n    delete ui;\\n}\\n```\\n\\n## Handling Socket.IO Events\\n\\nWe\'ll need to handle socket.io events in our functions they are bound to.\\n\\nFor example, we need to show received messages in the list view.\\n\\n```cpp\\nvoid MainWindow::OnNewMessage(std::string const& name,message::ptr const& data,bool hasAck,message::ptr &ack_resp)\\n{\\n    if(data->get_flag() == message::flag_object)\\n    {\\n        std::string msg = data->get_map()[\\"message\\"]->get_string();\\n        std::string name = data->get_map()[\\"username\\"]->get_string();\\n        QString label = QString::fromUtf8(name.data(),name.length());\\n        label.append(\':\');\\n        label.append(QString::fromUtf8(msg.data(),msg.length()));\\n        QListWidgetItem *item= new QListWidgetItem(label);\\n        //emit RequestAddListItem signal\\n        //so that \'AddListItem\' will be executed in UI thread.\\n        Q_EMIT RequestAddListItem(item);\\n    }\\n}\\n```\\n\\n## Wrapping Up: Sending the Message\\n\\nWhen `sendBtn` is clicked, we need to send the text in `messageEdit` to the chatroom.\\n\\nAdd the following code to `SendBtnClicked()`:\\n\\n```cpp\\nvoid MainWindow::SendBtnClicked()\\n{\\n    QLineEdit* messageEdit = this->findChild<QLineEdit*>(\\"messageEdit\\");\\n    QString text = messageEdit->text();\\n    if(text.length()>0)\\n    {\\n        QByteArray bytes = text.toUtf8();\\n        std::string msg(bytes.data(),bytes.length());\\n        _io->socket()->emit(\\"new message\\",msg);//emit new message\\n        text.append(\\":You\\");\\n        QListWidgetItem *item = new QListWidgetItem(text);\\n        item->setTextAlignment(Qt::AlignRight);\\n        Q_EMIT RequestAddListItem(item);\\n        messageEdit->clear();\\n    }\\n}\\n```\\n\\n## Further Reading\\n\\nYou can run the <a href=\\"https://github.com/socketio/socket.io-client-cpp/tree/master/examples/QT/SioChatDemo\\">demo project</a> to get a closer look. Before you run it, please follow the <a href=\\"https://github.com/socketio/socket.io-client-cpp#-with-cmake\\">instructions</a> to make the Socket.io client library.\\n\\nDon\'t forget to <a href=\\"https://github.com/socketio/socket.io-client-cpp\\">star the project</a> on GitHub to get updates!"},{"id":"/socket-io-on-ios/","metadata":{"permalink":"/blog/socket-io-on-ios/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-03-09-ios.md","source":"@site/blog/2015-03-09-ios.md","title":"Socket.IO on iOS","description":"We are pleased to announce the immediate availability of the Socket.IO Swift Client! Youll now be able to write code that runs natively on iOS and OSX, while maintaining the simplicity and expressiveness of the JavaScript client!","date":"2015-03-09T00:00:00.000Z","formattedDate":"March 9, 2015","tags":[],"readingTime":7,"hasTruncateMarker":true,"authors":[{"name":"Erik Little","title":"Maintainer of the iOS client","url":"https://twitter.com/nuclearace","image_url":"https://github.com/nuclearace.png","imageURL":"https://github.com/nuclearace.png"}],"frontMatter":{"title":"Socket.IO on iOS","slug":"/socket-io-on-ios/","authors":[{"name":"Erik Little","title":"Maintainer of the iOS client","url":"https://twitter.com/nuclearace","image_url":"https://github.com/nuclearace.png","imageURL":"https://github.com/nuclearace.png"}],"author_link":"https://twitter.com/nukeace"},"prevItem":{"title":"Socket.IO C++","permalink":"/blog/socket-io-cpp/"},"nextItem":{"title":"Socket.IO 1.3.5","permalink":"/blog/socket-io-1-3-5/"}},"content":"<video className=\\"gfyVidIframe\\" id=\\"gfyVid\\" autoPlay=\\"\\" loop=\\"\\" height=\\"574\\" width=\\"323\\"><source id=\\"webmsource\\" src=\\"//fat.gfycat.com/EssentialBlueElectriceel.webm\\" type=\\"video/webm\\" /><source id=\\"mp4source\\" src=\\"//giant.gfycat.com/EssentialBlueElectriceel.mp4\\" type=\\"video/mp4\\" /></video>\\n\\nWe are pleased to announce the immediate availability of the <a href=\\"https://github.com/socketio/socket.io-client-swift\\">Socket.IO Swift Client</a>! Youll now be able to write code that runs natively on **iOS** and **OSX**, while maintaining the simplicity and expressiveness of the JavaScript client!\\n\\n\x3c!--truncate--\x3e\\n\\n```swift\\nimport Foundation\\nlet socket = SocketIOClient(socketURL: \\"localhost:8880\\")\\nsocket.on(\\"important message\\") {data, ack in\\n    println(\\"Message for you! \\\\(data?[0])\\")\\n    ack?(\\"I got your message, and I\'ll send my response\\")\\n    socket.emit(\\"response\\", \\"Hello!\\")\\n}\\nsocket.connect()\\n```\\n\\nTo show how you can use it in a real project, Ill show you how to create a small Tic Tac Toe app like the one shown above.\\n\\n## Overview\\n\\
1nIn this tutorial well look at creating a small iOS app that demonstrates socket.io and iOS. If you learn better from looking at code you can look at it <a href=\\"https://github.com/nuclearace/socket.io-client-swift-example\\">here</a>. The point of the tutorial is not to explain developing an iOS app, but to demonstrate how you can incorporate `socket.io-client-swift` into your projects! So it is assumed you have a basic knowledge of XCode.\\nNote: This example uses Swift 1.2. However, 1.2 isnt much different from Swift 1.1, and the library has branches for Swift 1.1 and 1.2. The only difference in this guide is I use 1.2s expanded `if let` construct to avoid nesting.\\nNote 2: While this library is written in, and meant for, Swift applications, it can be used with Objective-C projects, but will require some extra work (youll probably need to create a Swift class that can interface with your Objective-C code, as not all methods in the client will be available to Objective-C i.e emit, onAny). See <a href=\\"https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_87\\">this</a> for more information.\\n\\n## Introduction\\n\\nI designed `socket.io-client-swift` to be as close to `socket.io-client` as I could. So many of the ways you do things in socket.io-client look similar here! This is not a step-by-step tutorial for making a Tic Tac Toe app, only adding the socket.io-client part of it.\\n\\n## Setting up the Project\\n\\nFrom Xcode, create a new project with the layout of single-view iOS application. You can name it whatever you like, Ill be naming mine `TicTacIOiOS`.\\nThe next step is getting the code for `socket.io-client-swift`, you can either use `git` to clone the repo to a directory, or simply download a <a href=\\"https://github.com/socketio/socket.io-client-swift/releases\\">release</a>. Either way you get it, the process of adding it to your project is the same. Simply drag the folder named SwiftIO to the same place you copied SocketRocket! (Again making sure you select copy.)\\nAnd thats it, the hardest part of putting our app together is done! At this point, if you want to test that its setup properly, try building and running the app, it should compile.\\n\\n### Adding Our Code\\n\\nNow, assuming youve created your user interface. Its time to add the code that will interface with our socket.io server!\\nIn our demo application we have one UIViewController subclass, named ViewController. All of our code will be added there. First, we need to add a member named `socket` of type `SocketIOClient` to our ViewController.\\n\\n```swift\\nlet socket = SocketIOClient(socketURL: \\"localhost:8900\\")\\n```\\n\\nNow, in our overridden `viewDidLoad` method we want to add two things, a method call that will add our handlers to our socket, and a call to connect our socket.\\n\\n```swift\\nself.addHandlers()\\nself.socket.connect()\\n```\\n\\n### Handlers\\n\\nNow that we have our method calls, its time to implement the method that adds the handlers!\\n\\n```swift\\nfunc addHandlers() {\\n    // Our socket handlers go here\\n}\\n```\\n\\nSince were about to add the handlers, I think its worth mentioning the syntax I use for closures in Swift. Swift has many different ways of expressing closures, and they can be found <a href=\\"https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html\\">here</a>. But the form I use for adding handlers is a trailing closure, without explicit type annotations. You can use other closure forms if you wish.\\nIm not going to show you all the handlers in our demo app here, just a few that demonstrate important things youll need to know when working with `socket.io-client-swift`.\\nThe first handler were going to add is one that will be called on any event, since its useful for debugging the API.\\n\\n```swift\\n// Using a shorthand parameter name for closures\\nself.socket.onAny {println(\\"Got event: \\\\($0.event), with items: \\\\($0.items)\\")}\\n```\\n\\nThe next handler that well add is the one that tells the app that the game has started.\\n\\n```swift\\nself.socket.on(\\"startGame\\") {[weak self] data, ack in\\n    self?.handleStart()\\n    return\\n}\\n```\\n\\nNow to explain some things. `[weak self]` is a capture list. It tells the compiler that the reference to self in this closure should not add to the reference count of self. This is so when the socket object goes out of scope, the capture made in the closure doesnt keep it from being deallocated. The first parameter in all `.on` callbacks is an optional NSArray, it will contain all the data received with the event, or nil. The second parameter in the callback is an optional with the type of AckEmitter. AckEmitter is simply a typealias of `(AnyObject...) -&gt; Void`. Well see this used later.\\nThe next handler well add is the one for a win.\\n\\n```swift\\nself.socket.on(\\"win\\") {[weak self] data, ack in\\n    if let name = data?[0] as? String, typeDict = data?[1] as? NSDictionary {\\n        self?.handleWin(name, type: typeDict)\\n    }\\n}\\n```\\n\\nAs mentioned before, this is new syntax for `if let` introduced in Swift 1.2. It simplifies optional unwrapping (pyramid of doom). The important thing to gather from this handler is that you do not need to force unwrap the array to get the object. Also note that a JSON object will be exposed to Swift as an NSDictionary.\\nAnother thing to note is that for almost all your handlers that have data, youll be doing some kind of optional unwrapping and type casting. This is an unfortunate consequence of working with JavaScript.\\nThe final handler that Ill demonstrate here is the one that handles whether the player wants to play again.\\n\\n```swift\\nself.socket.on(\\"gameReset\\") {data, ack in\\n    ack?(false)\\n}\\n```\\n\\nIn this simplified example, we simply send an acknowledgement to the server that we dont ever want to play again. Remember that AckEmitter has a variadic definition, so you can send multiple things at once if you wanted.\\n\\n### Emitting Events\\n\\nThe next thing you\'ll probably want to know is how to send events from the client. Youll be pleased to know that it has a form almost exactly the same as socket.io-client!\\nIn our ViewController we have a method that handles when a user wants to make a move. Without going into the logic of that, well show how we send the data to the server.\\n\\n```swift\\n@IBAction func btnClicked(btn:UIButton) {\\n    let 
1coord:(x:Int, y:Int)\\n\\n    // Long switch statement that determines what coord should be\\n\\n    self.socket.emit(\\"playerMove\\", coord.x, coord.y)\\n}\\n```\\n\\nThats all you need to do for sending data!\\nSome other examples of sending which arent covered in our demo are:\\n\\n### Sending JSON\\n\\nAs mentioned before, JSON in Swift is best represent as a Dictionary. Thankfully for you, you dont need to worry about turning it into something socket.io will understand, thats all done under-the-hood.\\n\\n```swift\\nlet myJSON = [\\n    \\"name\\": \\"bob\\"\\n]\\n\\nsocket.emit(\\"jsonTest\\", myJSON)\\n```\\n\\n### Sending Binary\\n\\nBinary data is also handled by the client, so you dont need to worry about it.\\n\\n```swift\\nlet data = \\"Hello, \\".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!\\nlet data2 = \\"World\\".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!\\n\\nsocket.emit(\\"dataTest\\", data, [\\"world\\": data2])\\n```\\n\\n### Requesting Acks\\n\\nThe client can also request that the server send an ack for an event. This is done by using the `emitWithAck` method which returns an object to which you can add a handler.\\n\\n```swift\\nsocket.emitWithAck(\\"needsAck\\", \\"test\\").onAck {data in\\n    println(\\"got ack with data: (data)\\")\\n}\\n```\\n\\n### A Note About Multitasking in iOS\\n\\nAs you probably know, iOS is very picky about what you can do in the background. As such, dont expect that your socket connection will survive in the background! Youll probably stop receiving events within seconds of the app going into the background. So its better to create a task that will gracefully close the connection when it enters the background (via AppDelegate), and then reconnect the socket when the app comes back into the foreground.\\nIf you want to learn more about the client, check out the <a href=\\"https://github.com/socketio/socket.io-client-swift/blob/master/README.md\\">README</a>! We also invite you to contribute by submitting issues, patches, documentation and examples."},{"id":"/socket-io-1-3-5/","metadata":{"permalink":"/blog/socket-io-1-3-5/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-03-03-1.3.5.md","source":"@site/blog/2015-03-03-1.3.5.md","title":"Socket.IO 1.3.5","description":"Socket.IO 1.3.5 addresses a parser issue. Upgrade recommended. Completely backwards-compatible.","date":"2015-03-03T00:00:00.000Z","formattedDate":"March 3, 2015","tags":[],"readingTime":0.07,"hasTruncateMarker":false,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.3.5","slug":"/socket-io-1-3-5/","authors":"rauchg"},"prevItem":{"title":"Socket.IO on iOS","permalink":"/blog/socket-io-on-ios/"},"nextItem":{"title":"Socket.IO 1.3.4","permalink":"/blog/socket-io-1-3-4/"}},"content":"Socket.IO **1.3.5** addresses a parser issue. Upgrade recommended. Completely backwards-compatible.\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-1-3-4/","metadata":{"permalink":"/blog/socket-io-1-3-4/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-02-14-1.3.4.md","source":"@site/blog/2015-02-14-1.3.4.md","title":"Socket.IO 1.3.4","description":"Socket.IO 1.3.4 corrects the 1.3.3 build that included extra unused code.","date":"2015-02-14T00:00:00.000Z","formattedDate":"February 14, 2015","tags":[],"readingTime":0.075,"hasTruncateMarker":false,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.3.4","slug":"/socket-io-1-3-4/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.3.5","permalink":"/blog/socket-io-1-3-5/"},"nextItem":{"title":"Socket.IO 1.3.3","permalink":"/blog/socket-io-1-3-3/"}},"content":"Socket.IO **1.3.4** corrects the `1.3.3` build that included extra unused code.\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.4/socket.io.min.js\\"><\/script>\\n```"},{"id":"/socket-io-1-3-3/","metadata":{"permalink":"/blog/socket-io-1-3-3/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-02-04-1.3.3.md","source":"@site/blog/2015-02-04-1.3.3.md","title":"Socket.IO 1.3.3","description":"Socket.IO 1.3.3 is a backwards-compatible recommended upgrade for everyone.","date":"2015-02-04T00:00:00.000Z","formattedDate":"February 4, 2015","tags":[],"readingTime":0.325,"hasTruncateMarker":false,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Socket.IO 1.3.3","slug":"/socket-io-1-3-3/","authors":"rauchg"},"prevItem":{"title":"Socket.IO 1.3.4","permalink":"/blog/socket-io-1-3-4/"},"nextItem":{"title":"Native Socket.IO and Android","permalink":"/blog/native-socket-io-and-android/"}},"content":"Socket.IO **1.3.3** is a backwards-compatible **recommended upgrade** for everyone.\\n\\n- It addresses a bug in the parser that c
1ould break the decoder with maliciously-crafted binary packets.\\n\\n- We now *warn* about errors in the console if you dont manually specify an `error` event handler for `Socket` objects on the server.\\n\\nAs usual, you can grab the latest client from the CDN!\\n\\n```html\\n<script src=\\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.3/socket.io.min.js\\"><\/script>\\n```"},{"id":"/native-socket-io-and-android/","metadata":{"permalink":"/blog/native-socket-io-and-android/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2015-01-20-native-socket-io-and-android.md","source":"@site/blog/2015-01-20-native-socket-io-and-android.md","title":"Native Socket.IO and Android","description":"In this tutorial well learn how to create a chat client that communicates with a Socket.IO Node.JS chat server, with our native Android Client! If you want to jump straight to the code, it\'s on GitHub. Otherwise, read on!","date":"2015-01-20T00:00:00.000Z","formattedDate":"January 20, 2015","tags":[],"readingTime":3.47,"hasTruncateMarker":true,"authors":[{"name":"Naoyuki Kanezawa","title":"Maintainer of Socket.IO","url":"https://twitter.com/nkzawa","image_url":"https://github.com/nkzawa.png","imageURL":"https://github.com/nkzawa.png"}],"frontMatter":{"title":"Native Socket.IO and Android","slug":"/native-socket-io-and-android/","authors":[{"name":"Naoyuki Kanezawa","title":"Maintainer of Socket.IO","url":"https://twitter.com/nkzawa","image_url":"https://github.com/nkzawa.png","imageURL":"https://github.com/nkzawa.png"}]},"prevItem":{"title":"Socket.IO 1.3.3","permalink":"/blog/socket-io-1-3-3/"},"nextItem":{"title":"Introducing Socket.IO 1.0","permalink":"/blog/introducing-socket-io-1-0/"}},"content":"<img class=\\"aligncenter size-full wp-image-626\\" src=\\"/images/androidchat.gif\\" alt=\\"android chat demo\\" width=\\"338\\" height=\\"600\\"/>\\n\\nIn this tutorial well learn how to create a chat client that communicates with a Socket.IO <a href=\\"https://github.com/socketio/socket.io/blob/master/examples/chat/index.js\\">Node.JS chat server</a>, with our <a href=\\"https://github.com/socketio/socket.io-client-java\\">native Android Client</a>! If you want to jump straight to the code, it\'s on <a href=\\"https://github.com/nkzawa/socket.io-android-chat\\">GitHub</a>. Otherwise, read on!\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nTo follow along, start by cloning the repository: <a title=\\"socket.io-android-chat\\" href=\\"https://github.com/nkzawa/socket.io-android-chat\\" target=\\"_blank\\">socket.io-android-chat</a>.\\n\\nThe app has the following features:\\n\\n- Sending a message to all users joining to the room.\\n- Notifies when each user joins or leaves.\\n- Notifies when an user start typing a message.\\n\\nSocket.IO provides an event-oriented API that works across all networks, devices and browsers. It\'s incredibly robust (works even behind corporate proxies!) and highly performant, which is very suitable for multiplayer games or realtime communication.\\n\\n## Installing the Dependencies\\n\\nThe first step is to install the Java Socket.IO client with <a href=\\"https://developer.android.com/tools/building/configuring-gradle.html\\" target=\\"_blank\\">Gradle</a>.\\n\\nFor this app, we just add the dependency to `build.gradle`:\\n\\n```gradle\\ndependencies {\\n    implementation (\'io.socket:socket.io-client:2.0.0\') {\\n        exclude group: \'org.json\', module: \'json\'\\n    }\\n}\\n```\\n\\nWe must remember adding the internet permission to `AndroidManifest.xml`.\\n\\n```xml\\n\x3c!-- app/AndroidManifest.xml --\x3e\\n<manifest xmlns:android=\\"http://schemas.android.com/apk/res/android\\">\\n    <uses-permission android:name=\\"android.permission.INTERNET\\" />\\n    ...\\n</manifest>
1\\n```\\n\\nNow we can use Socket.IO on Android!\\n\\n## Using socket in Activity and Fragment\\n\\nFirst, we have to initialize a new instance of Socket.IO as follows:\\n\\n```java\\nimport io.socket.client.IO;\\nimport io.socket.client.Socket;\\n\\nprivate Socket mSocket;\\n{\\n    try {\\n        mSocket = IO.socket(\\"http://chat.socket.io\\");\\n    } catch (URISyntaxException e) {}\\n}\\n\\n@Override\\npublic void onCreate(Bundle savedInstanceState) {\\n    super.onCreate(savedInstanceState);\\n    mSocket.connect();\\n}\\n```\\n\\n`IO.socket()` returns a socket for `http://chat.socket.io` with the default options. Notice that the method caches the result, so you can always get a same `Socket` instance for an url from any Activity or Fragment.\\nAnd we explicitly call `connect()` to establish the connection here (unlike the JavaScript client). In this app, we use `onCreate` lifecycle callback for that, but it actually depends on your application.\\n\\n## Emitting events\\n\\nSending data looks as follows. In this case, we send a string but you can do JSON data too with the <a href=\\"http://developer.android.com/reference/org/json/package-summary.html\\" target=\\"_blank\\">org.json</a> package, and even binary data is supported as well!\\n\\n```java\\nprivate EditText mInputMessageView;\\n\\nprivate void attemptSend() {\\n    String message = mInputMessageView.getText().toString().trim();\\n    if (TextUtils.isEmpty(message)) {\\n        return;\\n    }\\n\\n    mInputMessageView.setText(\\"\\");\\n    mSocket.emit(\\"new message\\", message);\\n}\\n```\\n\\n## Listening on events\\n\\nLike I mentioned earlier, Socket.IO is **bidirectional**, which means we can send events to the server, but also at any time during the communication the server can send events to us.\\n\\nWe then can make the socket listen an event on `onCreate` lifecycle callback.\\n\\n```java\\n@Override\\npublic void onCreate(Bundle savedInstanceState) {\\n    super.onCreate(savedInstanceState);\\n\\n    mSocket.on(\\"new message\\", onNewMessage);\\n    mSocket.connect();\\n}\\n```\\n\\nWith this we listen on the `new message` event to receive messages from other users.\\n\\n```java\\nimport io.socket.emitter.Emitter;\\n\\nprivate Emitter.Listener onNewMessage = new Emitter.Listener() {\\n    @Override\\n    public void call(final Object... args) {\\n        getActivity().runOnUiThread(new Runnable() {\\n            @Override\\n            public void run() {\\n                JSONObject data = (JSONObject) args[0];\\n                String username;\\n                String message;\\n                try {\\n                    username = data.getString(\\"username\\");\\n                    message = data.getString(\\"message\\");\\n                } catch (JSONException e) {\\n                    return;\\n                }\\n\\n                // add the message to view\\n                addMessage(username, message);\\n            }\\n        });\\n    }\\n};\\n```\\n\\nThis is what `onNewMessage` looks like. A listener is an instance of `Emitter.Listener` and must be implemented the `call` method. Youll notice that inside of `call()` is wrapped by `Activity#runOnUiThread()`, that is because the callback is always called on another thread from Android UI thread, thus we have to make sure that adding a message to view happens on the UI thread.\\n\\n## Managing Socket State\\n\\nSince an Android Activity has its own lifecycle, we should carefully manage the state of the socket also to avoid problems like memory leaks. In this app, we\u2019ll close the socket connection and remove all listeners on `onDestroy` callback of Activity.\\n\\n```java\\n@Override\\npublic void onDestroy() {\\n    super.onDestroy();\\n\\n    mSocket.disconnect();\\n    mSocket.off(\\"new message\\", onNewMessage);\\n}\\n```\\n\\nCalling `off()` removes the listener of the `new message` event.\\n\\n## Further reading\\n\\nIf you want to explore more, I recommend you look into:\\n\\n- Other features of this app. They are just implemented with `emit()`, `on()` and `off()`.\\n\\n- The [documentation](https://socketio.github.io/socket.io-client-java/installation.html) of the Java Socket.IO client\\n\\n- Many other great Socket.IO implementations created by the community!"},{"id":"/introducing-socket-io-1-0/","metadata":{"permalink":"/blog/introducing-socket-io-1-0/","editUrl":"https://github.com/socketio/socket.io-website/edit/main/blog/2014-05-28-1.0.0.md","source":"@site/blog/2014-05-28-1.0.0.md","title":"Introducing Socket.IO 1.0","description":"The first version of Socket.IO was created shortly after Node.JS made its f
1irst appearance. I had been looking for a framework that easily enabled me to push data from a server to a client for a long time, and even had tried other approaches to server-side JavaScript.","date":"2014-05-28T00:00:00.000Z","formattedDate":"May 28, 2014","tags":[],"readingTime":11.885,"hasTruncateMarker":true,"authors":[{"name":"Guillermo Rauch","title":"Maintainer of Socket.IO","url":"https://twitter.com/rauchg","imageURL":"https://github.com/rauchg.png","key":"rauchg"}],"frontMatter":{"title":"Introducing Socket.IO 1.0","slug":"/introducing-socket-io-1-0/","authors":"rauchg"},"prevItem":{"title":"Native Socket.IO and Android","permalink":"/blog/native-socket-io-and-android/"}},"content":"The first version of Socket.IO was created shortly after Node.JS made its first appearance. I had been looking for a framework that easily enabled me to push data from a server to a client for a long time, and even had tried other approaches to server-side JavaScript.\\n\\n\x3c!--truncate--\x3e\\n\\nAt the time, the main focus was on an interface equivalent to the upcoming `WebSocket` API that was in the process of standardization. I was lucky to receive a lot of feedback from the community at the time (including Node.JS\'s creator) that helped shape the project into something significantly more useful.\\n\\nSocket.IO has thus become the `EventEmitter` of the web. Today I want to talk about the work that has gone into 1.0 to round up this vision.\\n\\nThere\'s a lot to say about Socket.IO 1.0, so if you\'re short in time, feel free to jump to the parts that are most interesting to you:\\n\\n1. [New engine](#new-engine)\\n2. [Binary support](#binary-support)\\n3. [Automated testing](#automated-Testing)\\n4. [Scalability](#scalability)\\n5. [Integration](#integration)\\n6. [Better debugging](#better-debugging)\\n7. [Streamlined APIs](#streamlined-apis)\\n8. [CDN delivery](#cdn-delivery)\\n9. [Future innovation](#future-innovation)\\n10. [Credits](#credits)\\n\\n\\n## New engine\\n\\nThe Socket.IO codebase no longer deals with transports and browser incompatibilities. That work has been relegated to a new module we\'ve been perfecting for months called <a href=\\"http://github.com/automattic/engine.io\\">Engine.IO</a> that implements a WebSocket-like API.\\n\\nThe benefits of this particular modularization can\'t be understated:\\n\\n- For the Socket.IO end user, nothing changes. Just drop-in the new version!\\n- A tremendous simplification in terms of codebase size and testing surface\\n  - The Socket.IO Server is now only 1234 lines of code.\\n  - The Socket.IO Client is now only 976 lines of code.\\n- Future-proof flexibility\\n  - If `WebSocket` is the only transport you want to support moving forward, Engine.IO (with all its browser hacks and workarounds) can be seamlessly removed.\\n  - Alternative transports such as vanilla Node.JS TCP Sockets or <a href=\\"https://developer.chrome.com/apps/socket\\">Google Chrome Sockets</a> can be trivially implemented.\\n\\nThis separation has also allowed us to innovate and perfect the transport layer. One of my favorite improvements was introducing the idea of what I call *transport feature detection*.\\n\\nOnce upon a time in the web, it was extremely common to simply sniff User Agents to make decisions of what APIs to use or what behaviors to enable. As JavaScript codebases became more complex and mature, it became obvious that in order to *maximize reliability*, it made more sense to directly test the APIs to see if they would behave as expected.\\n\\nFor example, simply checking that the *JSON* global is present does not mean that *JSON.stringify* works, or even exists. It could have simply meant that the user defined a JSON global of their own, or the environment could have a broken JSON implementation.\\n\\nSocket.IO never assumes that `WebSocket` will just work, because in practice there\'s a good chance that it won\'t. Instead, it establishes a connection with XHR or JSONP right away, and then attempts to **upgrade** the connection to WebSocket. Compared to the fallback method which relies on timeouts, this means that *none of your users will have a degraded experience*.\\n\\n\\
1n## Binary support\\n\\nUsers have been asking for the ability to send binary data for a while, especially after `WebSocket` added support for it.\\n\\nThe main issue was that if we had modeled our binary support after the `WebSocket` API, its usefulness would have been fairly limited. `WebSocket` requires that you put your Socket either into &#8220;string mode&#8221; or &#8220;binary mode&#8221;:\\n\\n```js\\nvar socket = new WebSocket(\'ws://localhost\');\\nsocket.binaryType = \'arraybuffer\';\\nsocket.send(new ArrayBuffer);\\n```\\n\\nThis is good for a low-level API, which is why Engine.IO <a href=\\"https://github.com/automattic/engine.io-client#sending-and-receiving-binary\\">now supports it</a>, but application developers most likely don\'t want to send *only blobs*, or encode everything as a blob manually prior to sending it out.\\n\\nSocket.IO now supports emitting `Buffer` (from Node.JS), `Blob`, `ArrayBuffer` and even `File`, as part of any datastructure:\\n\\n```js\\nvar fs = require(\'fs\');\\nvar io = require(\'socket.io\')(3000);\\nio.on(\'connection\', function(socket){\\n  fs.readFile(\'image.png\', function(err, buf){\\n    // it\'s possible to embed binary data\\n    // within arbitrarily-complex objects\\n    socket.emit(\'image\', { image: true, buffer: buf });\\n  });\\n});\\n```\\n\\nTo test how useful it would be to support binary in this particular way (and as a virtualization geek), I decided to replicate the <a href=\\"http://en.wikipedia.org/wiki/Twitch_Plays_Pok%C3%A9mon\\">Twitch Plays Pokemon</a> experiment 100% in JavaScript. Using a <a href=\\"https://github.com/grantgalitz/GameBoy-Online\\">JavaScript gameboy emulator</a>, <a href=\\"http://github.com/automattic/node-canvas\\">node-canvas</a>, socket.io we came up with a server-rendered collaborative game that even works on IE8. Check it out on https://weplay.io (<a href=\\"https://github.com/guille/weplay\\">source code here</a>).\\n\\n<video id=\\"weplay-vid\\" data-setup=\\"{&quot;autoplay&quot;:true,&quot;loop&quot;:true, &quot;techOrder&quot;: [&quot;html5&quot;, &quot;flash&quot;], &quot;height&quot;: 300}\\" className=\\"video-js vjs-default-skin\\" autoPlay loop width=\\"100%\\" poster=\\"https://i.cloudup.com/aNZqxnZzHv.png\\"><source src=\\"https://i.cloudup.com/transcoded/KL-0r-E2Gj.mp4\\" type=\\"video/mp4\\" /></video>\\n\\nThe relevant code that sends the image data is:\\n\\n```js\\nself.canvas.toBuffer(function(err, buf){\\n  if (err) throw err;\\n  io.emit(\'frame\', buf);\\n});\\n```\\n\\nThe next experiment was to run an instance of <a href=\\"http://wiki.qemu.org/Main_Page\\">QEMU</a> running an image of Windows XP, in honor of <a href=\\"http://indianexpress.com/article/technology/technology-others/windows-xp-end-of-support-today/\\">its retirement</a>. Every player gets a 15 second turn to control the machine. Check out the demo on http://socket.computer. Here\'s a video of your typical inception scenario:\\n\\n<video id=\\"computer-vid\\" data-setup=\\"{&quot;autoplay&quot;:true,&quot;loop&quot;:true, &quot;techOrder&quot;: [&quot;html5&quot;, &quot;flash&quot;], &quot;height&quot;: 300}\\" className=\\"video-js vjs-default-skin\\" autoPlay loop width=\\"100%\\"><source src=\\"https://i.cloudup.com/transcoded/Cuqn5OLmcl.mp4\\" type=\\"video/mp4\\" /></video>\\n\\nA key part of putting together this demo was connecting to the QEMU VNC server and implementing the RFB protocol. As it\'s usually the case with Node.JS, the solution was a `npm search rfb` away.\\n\\nEssentially, in order to minimize latency and have the best performance, it\'s best to notify clients *only* of the pieces of the screen that changed. For example, if you move your mouse around, only little pieces of the screen that surround the cursor are broadcasted. The <a href=\\"https://github.com/sidorares/node-rfb2\\">node-rfb2</a> module gives us a `rect` event with objects like the following:\\n\\n```js\\n{\\n  x: 103,\\n  y: 150,\\n  width: 200,\\n  height: 250,\\n  data: Buffer\\n}\\n```\\n\\nIt then became clear to me that our support for binary data would be genuinely useful. All I had to do was call `io.emit` to pass that object around, and let Socket.IO do the rest.\\n\\nJust for fun, I also installed and ran one of my favorite first person shooters:\\n\\n<video id=\\"cs-vid\\" data-setup=\\"{&quot;autoplay&quot;:true,&quot;loop&quot;:true, &quot;techOrder&quot;: [&quot;html5&quot;, &quot;flash&quot;], &quot;height&quot;: 300}\\" className=\\"video-js vjs-default-skin\\" autoPlay loop width=\\"100%\\"><source src=\\"https://i.cloudup.com/transcoded/Ra6PJnoLBq.mp4\\" type=\\"video/mp4\\" /></video>\\n\\n## Automated Testing\\n\\nEvery commit to the Socket.IO codebase now triggers a testing matrix totaling to 25 browsers, including Android and iOS.\\n\\nWe accomplish this by having `make test` seamlessly set up a reverse tunnel to ephemeral ports in your computer (thus making it accessible from the outside world), and have them execute on the Sauce Labs cloud, which is in charge of virtualizing and executing browsers on all the environments we care about.\\n\\n<img src=\\"https://i.cloudup.com/wuvWoEV3EH.png\\" alt=\\"\\"/>\\n\\n\\n## Scalability\\n\\nWe simplified the approach towards rooms and multi-node scalability dramatically. Instead of storing and/or replicating data across nodes, Socket.IO is now only concerned with passing events around.\\n\\nIf you want to scale out Socket.IO to multiple nodes, it now comes down to two simple steps:\\n\\n- Turn on sticky load balancing (for example by origin IP address). This ensures that long-polling connections for example always route requests to the same node where buffers of messages could be stored.\\n- Implement the <a href=\\"https://github.com/automattic/socket.io-redis\\">socket.io-redis</a> adapter.\\n\\n```js\\nvar io = require(\'socket.io\')(3000);\\nvar redis = require(\'socket.io-redis\');\\nio.adapter(redis({ host: \'localhost\', port: 6379 }));\\n```\\n\\nWe have deprecated the `Socket#set` and `Socket#get` APIs. Packets now simply get encoded and distributed to other nodes whenever you broadcast, and we don\'t deal with storage.\\n\\nThis leads directly into our next goal: integration with other backends.\\n\\n\\
1n## Integration\\n\\nChances are good that your existing application deployments are written in a variety of languages and frameworks, and are not just limited to Node.JS. Even if it was all Node.JS, you probably at some point want to separate concerns of your application into different processes.\\n\\nOne of the processes might be in charge of hosting the Socket.IO server, accepting connections, performing authentication, etc, and then another part of your backend might end up in charge of *producing* messages.\\n\\nTo that end we\'re introducing the <a href=\\"https://github.com/automattic/socket.io-emitter\\">socket.io-emitter</a> project which hooks into <a href=\\"https://github.com/automattic/socket.io-redis\\">socket.io-redis</a> to easily allow you to emit events to browsers from anywhere:\\n\\n```js\\nvar io = require(\'socket.io-emitter\')();\\nsetInterval(function(){\\n  io.emit(\'time\', new Date);\\n}, 5000);\\n```\\n\\nTony Kovanen already created a <a href=\\"https://github.com/rase-/socket.io-php-emitter\\">PHP implementation</a>:\\n\\n```js\\n<?php\\n$emitter = new SocketIOEmitter(array(\'port\' => \'6379\', \'host\' => \'127.0.0.1\'));\\n$emitter->emit(\'event\', \'wow\');\\n?>\\n```\\n\\nThis makes it really easy to turn any existing application into a realtime application!\\n\\n\\n## Better debugging\\n\\nSocket.IO is now completely instrumented by a minimalistic yet tremendously powerful utility called <a href=\\"https://github.com/visionmedia/debug\\">debug</a> by TJ Holowaychuk.\\n\\nIn the past, the Socket.IO server would default to logging everything out to the console. This turned out to be annoyingly verbose for many users (although extremely useful for others), and violates the Rule of Silence of the <a href=\\"http://en.wikipedia.org/wiki/Unix_philosophy#Eric_Raymond.E2.80.99s_17_Unix_Rules\\">Unix Philosophy</a>:\\n\\n<blockquote>\\n  **Rule of Silence**<br/>\\n  Developers should design programs so that they do not print unnecessary output. This rule aims to allow other programs and developers to pick out the information they need from a program\'s output without having to parse  verbosity.\\n\\n</blockquote>\\nThe basic idea is that each module used by Socket.IO provides different debugging scopes that give you insight into the internals. By default, all output is suppressed, and you can opt into seeing messages by supplying the `DEBUG` env variable (Node.JS) or the `localStorage.debug` property (Browsers).\\n\\nYou can see it in action for example on our homepage:\\n\\n<video id=\\"debugging-vid\\" data-setup=\\"{&quot;autoplay&quot;:true,&quot;loop&quot;:true, &quot;techOrder&quot;: [&quot;html5&quot;, &quot;flash&quot;], &quot;height&quot;: 300}\\" className=\\"video-js vjs-default-skin\\" autoPlay loop width=\\"100%\\"><source src=\\"https://i.cloudup.com/transcoded/IL9alTr0eO.mp4\\" type=\\"video/mp4\\" /></video>\\n\\n\\n## Streamlined APIs\\n\\nThe `socket.io` module now exports the attachment function directly (previously `.listen`).<br/>\\nIt\'s even easier now to attach socket.io to a HTTP server:\\n\\n```js\\nvar srv = require(\'http\').Server();\\nvar io = require(\'socket.io\')(srv);\\n```\\n\\nor to make it listen on some port:\\n\\n```js\\nvar io = require(\'socket.io\')(8080);\\n```\\n\\nBefore, to refer to everyone connected you had to use `io.sockets`. Now you can call directly on `io`:\\n\\n```js\\nio.on(\'connection\', function(socket){\\n  socket.emit(\'hi\');\\n});\\nio.emit(\'hi everyone\');\\n```\\n\\n\\n## CDN delivery\\n\\nOne of the best decisions we made early on was that implementing a Socket.IO server would not only give you access to the realtime protocol, but Socket.IO itself would also serve the client.\\n\\nNormally, all you have to do is to include a snippet like this:\\n\\n```js\\n<script src=\\"/socket.io/socket.io.js\\"><\/script>\\n```\\n\\nIf you want to optimize access to the client by serving it near your users, provide the maximum level of gzip compression (thanks to Google\'s <a href=\\"https://code.google.com/p/zopfli/\\">zopfli</a> and proper support for caching, you can now use our CDN. It\'s free, forever, and has built-in SSL supp
1ort:\\n\\n```js\\n<script src=\\"https://cdn.socket.io/socket.io-1.0.0.js\\"><\/script>\\n```\\n\\n## Future innovation\\n\\nThe core Socket.IO projects will continue to improve with lots of more frequent releases, with the sole goal of improving reliability, speed and making the codebase smaller and easier to maintain. Socket.IO 2.0 will probably see us ditching support for some older browsers, and not bundling some modules like the JSON serializer.\\n\\nMost of the innovation in the Socket.IO world will happen outside of the core codebases. The most important projects that I\'ll be closely watching are the following:\\n\\n### socket.io-stream\\n\\nBy adding this plugin, you\'ll be able to send `Stream` objects so that you can write memory-efficient programs. In the first example we loaded a file into memory prior to emitting it, but the following should be possible:\\n\\n```js\\nvar fs = require(\'fs\');\\nvar io = require(\'socket.io\')(3000);\\nrequire(\'socket.io-stream\')(io);\\nio.on(\'connection\', function(socket){\\n  io.emit(fs.createReadStream(\'file.jpg\'));\\n});\\n```\\n\\nAnd on the client side you\'ll receive a `Stream` object that emits `data` events.\\n\\n### Tooling\\n\\nWhen you use Socket.IO you don\'t care about transports, packets, frames, TCP or WebSocket. You care about what events are sent back and forth.\\n\\n<a href=\\"https://cloudup.com/cBxkAW3sqpH\\"><img src=\\"https://i.cloudup.com/_Jsiiabyfr.png\\" alt=\\"\\"/></a>\\n\\nOur goal is to have plugins for Web Inspector, Firefox Developer Tools that allow you to easily introspect what events are being sent, when, and what their parameters are.\\n\\nThis project is being led by the talented Nick LaGrow (<a href=\\"https://github.com/nlagrow\\">Github</a>), Samaan Ghani (<a href=\\"https://github.com/samaanghani\\">Github</a>) and David Cummings (<a href=\\"https://twitter.com/dece\\">Twitter</a>).\\n\\n\\n### New languages and frameworks\\n\\nA lot of effort has gone into specing and documenting the <a href=\\"https://github.com/automattic/engine.io-protocol\\">Engine.IO protocol</a> and <a href=\\"https://github.com/automattic/socket.io-protocol\\">Socket.IO protocol</a>.\\n\\nThe main goal behind this is that the Node.JS servers and clients become the reference implementations for many other languages and frameworks. Interoperability within the larger ecosystem is one of our biggest goals for 2014 and beyond.\\n\\n\\n## Credits\\n\\nThis release has been a big team effort. Special thanks go out to our new core team:\\n\\n- Tony Kovanen (<a href=\\"http://github.com/rase-\\">Github</a> / <a href=\\"http://twitter.com/TonyKovanen\\">Twitter</a>) for his amazing work on Engine.IO binary support and research into a variety of workarounds to support all versions of iOS and Internet Explorer, his help in putting together this website and rounding up the docs.\\n\\n- Kevin Roark (<a href=\\"http://github.com/kevin-roark\\">Github</a>) for the entire development of the new Socket.IO parser on top of Engine, the Socket.IO Computer demo, and help with docs, issues and pull requests.\\n\\n- Roman Shtylman (<a href=\\"http://github.com/defunctzombie\\">Github</a> / <a href=\\"http://twitter.com/defunctzombie\\">Twitter</a>) for his work on zuul and localtunnel, crucial to our testing architecture and our mission of reliability.\\n\\nAnd in no particular order:\\n\\n- Jay Borenstein (<a href=\\"http://www.linkedin.com/in/jayborenstein\\">LinkedIn</a>) for selecting Socket.IO as one of the projects to mentor students on Open Source engineering as part of the <a href=\\"https://www.facebook.com/notes/facebook-engineering/facebook-open-academy-bringing-open-source-to-cs-curricula/10151806121378920\\">Open Academy</a> project.\\n\\n- Michael Srb (<a href=\\"https://github.com/xixixao\\">Github</a>), Mark Mokryn (<a href=\\"https://github.com/mokesmokes\\">Github</a>), Eugen Dueck (<a href=\\"http://github.com/eugendueck\\">Github</a>), Afshin Mehrabani (<a href=\\"http://github.com/afshinm\\">Github</a>), Christoph Dorn (<a href=\\"https://github.com/cadorn\\">Github</a>) and Mikito Takada (<a href=\\"http://github.com/mixu\\">Github</a>) for several key Engine.IO patches.\\n\\n- Grant Timmerman (<a href=\\"http://github.com/grant\\">Github</a> / <a href=\\"https://twitter.com/granttimmerman\\">Twitter</a>) for his outstanding work on the new Socket.IO <a href=\\"http://new.socket.io/demos/chat/\\">example chat application</a>, and multiple patches and issues investigation.\\n\\n- Jxck (<a href=\\"http://github.com/jxck\\">Github</a> / <a href=\\"https://twitter.com/Jxck_\\">Twitter</a>) for his work on translation, documentations and patches. \u3042\u308a\u304c\u3068\u3046\\n\\
1n- Arnout Kazemier (<a href=\\"http://github.com/3rdEden\\">Github</a> / <a href=\\"https://twitter.com/3rdEden\\">Twitter</a>) for his multiple contributions to Engine.IO and Socket.IO\\n\\n- Sauce Labs (<a href=\\"https://github.com/saucelabs\\">Github</a> / <a href=\\"https://twitter.com/saucelabs\\">Twitter</a>) for supporting open source projects with free testing infrastructure.\\n\\n- Shihui Song (<a href=\\"https://github.com/sweetiesong\\">Github</a>), Qiming Fang (<a href=\\"https://github.com/qimingfang\\">Github</a>) and Erluo Li for their work on testing infrastructure.\\n\\n- Julian Salazar (<a href=\\"https://github.com/j-salazar\\">Github</a>) and Tianyiu Liu (<a href=\\"https://github.com/poohlty\\">Github</a>) for their work on reconnection and ongoing research into resource sharing between browser tabs and messages synchronization.\\n\\n- Gal Koren (<a href=\\"https://github.com/get\\">Github</a>) for his fantastic work into modularization of the codebases.\\n\\n- Matt Walker (<a href=\\"https://twitter.com/mcfwalker\\">Twitter</a>) for the beautiful Socket.IO logo.\\n\\nFinally, I\'m very grateful to my company <a href=\\"http://automattic.com/\\">Automattic</a> for being a great home to Open Source innovation."}]}')}}]);

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.