├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build-examples.yml │ ├── ci-browser.yml │ ├── ci.yml │ └── publish.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── docs ├── README.md ├── engine.io-protocol │ ├── v3-test-suite │ │ ├── .gitignore │ │ ├── index.html │ │ ├── node-imports.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── test-suite.js │ ├── v3.md │ ├── v4-current.md │ └── v4-test-suite │ │ ├── .gitignore │ │ ├── index.html │ │ ├── node-imports.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── test-suite.js └── socket.io-protocol │ ├── v3.md │ ├── v4.md │ ├── v5-current.md │ └── v5-test-suite │ ├── .gitignore │ ├── index.html │ ├── node-imports.js │ ├── package-lock.json │ ├── package.json │ └── test-suite.js ├── examples ├── .gitignore ├── ReactNativeExample │ ├── .bundle │ │ └── config │ ├── .eslintrc.js │ ├── .gitignore │ ├── .prettierrc.js │ ├── .watchmanconfig │ ├── App.tsx │ ├── Gemfile │ ├── README.md │ ├── __tests__ │ │ └── App.test.tsx │ ├── android │ │ ├── app │ │ │ ├── build.gradle │ │ │ ├── debug.keystore │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── reactnativeexample │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ └── MainApplication.kt │ │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── app.json │ ├── babel.config.js │ ├── index.js │ ├── ios │ │ ├── .xcode.env │ │ ├── Podfile │ │ ├── ReactNativeExample.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── ReactNativeExample.xcscheme │ │ ├── ReactNativeExample │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.mm │ │ │ ├── Images.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Info.plist │ │ │ ├── LaunchScreen.storyboard │ │ │ └── main.m │ │ └── ReactNativeExampleTests │ │ │ ├── Info.plist │ │ │ └── ReactNativeExampleTests.m │ ├── jest.config.js │ ├── metro.config.js │ ├── package.json │ ├── server │ │ ├── index.js │ │ └── package.json │ ├── socket.js │ ├── tsconfig.json │ └── yarn.lock ├── angular-todomvc │ ├── .browserslistrc │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── angular.json │ ├── assets │ │ └── demo.gif │ ├── e2e │ │ ├── protractor.conf.js │ │ ├── src │ │ │ ├── app.e2e-spec.ts │ │ │ └── app.po.ts │ │ └── tsconfig.json │ ├── karma.conf.js │ ├── package.json │ ├── server.ts │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ └── store.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.css │ │ └── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── tslint.json ├── basic-crud-application │ ├── README.md │ ├── angular-client │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── README.md │ │ ├── angular.json │ │ ├── package.json │ │ ├── src │ │ │ ├── app │ │ │ │ ├── app.component.css │ │ │ │ ├── app.component.html │ │ │ │ ├── app.component.spec.ts │ │ │ │ ├── app.component.ts │ │ │ │ ├── app.config.ts │ │ │ │ ├── app.routes.ts │ │ │ │ └── store.ts │ │ │ ├── assets │ │ │ │ └── .gitkeep │ │ │ ├── environments │ │ │ │ ├── environment.development.ts │ │ │ │ └── environment.ts │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── main.ts │ │ │ └── styles.css │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ └── tsconfig.spec.json │ ├── common │ │ └── events.ts │ ├── server-postgres-cluster │ │ ├── README.md │ │ ├── docker-compose.yml │ │ ├── lib │ │ │ ├── app.js │ │ │ ├── cluster.js │ │ │ ├── index.js │ │ │ ├── todo-management │ │ │ │ ├── todo.handlers.js │ │ │ │ └── todo.repository.js │ │ │ └── util.js │ │ └── package.json │ ├── server │ │ ├── lib │ │ │ ├── app.ts │ │ │ ├── index.ts │ │ │ ├── todo-management │ │ │ │ ├── todo.handlers.ts │ │ │ │ └── todo.repository.ts │ │ │ └── util.ts │ │ ├── package.json │ │ ├── test │ │ │ └── todo-management │ │ │ │ └── todo.tests.ts │ │ └── tsconfig.json │ └── vue-client │ │ ├── .gitignore │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── styles.css │ │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── main.js │ │ ├── socket.js │ │ └── stores │ │ │ └── todo.js │ │ ├── vue.config.js │ │ └── yarn.lock ├── basic-websocket-client │ ├── README.md │ ├── bundle │ │ └── socket.io.min.js │ ├── check-bundle-size.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ └── index.js │ └── test │ │ └── index.js ├── chat │ ├── README.md │ ├── index.js │ ├── package.json │ └── public │ │ ├── index.html │ │ ├── main.js │ │ └── style.css ├── cluster-engine-node-cluster │ ├── README.md │ ├── client.js │ ├── package.json │ └── server.js ├── cluster-engine-redis │ ├── README.md │ ├── client.js │ ├── compose.yaml │ ├── package.json │ └── server.js ├── cluster-haproxy │ ├── README.md │ ├── docker-compose.yml │ ├── haproxy.cfg │ └── server │ │ ├── Dockerfile │ │ ├── index.js │ │ ├── package.json │ │ └── public │ │ ├── index.html │ │ ├── main.js │ │ └── style.css ├── cluster-httpd │ ├── README.md │ ├── docker-compose.yml │ ├── httpd.conf │ └── server │ │ ├── Dockerfile │ │ ├── index.js │ │ ├── package.json │ │ └── public │ │ ├── index.html │ │ ├── main.js │ │ └── style.css ├── cluster-nginx │ ├── README.md │ ├── client │ │ ├── Dockerfile │ │ ├── index.js │ │ └── package.json │ ├── docker-compose.yml │ ├── nginx.conf │ └── server │ │ ├── Dockerfile │ │ ├── index.js │ │ ├── package.json │ │ └── public │ │ ├── index.html │ │ ├── main.js │ │ └── style.css ├── cluster-traefik │ ├── README.md │ ├── docker-compose.yml │ ├── server │ │ ├── Dockerfile │ │ ├── index.js │ │ ├── package.json │ │ └── public │ │ │ ├── index.html │ │ │ ├── main.js │ │ │ └── style.css │ └── traefik.yml ├── connection-state-recovery-example │ ├── README.md │ ├── assets │ │ └── csr.gif │ ├── cjs │ │ ├── .codesandbox │ │ │ ├── Dockerfile │ │ │ └── tasks.json │ │ ├── index.html │ │ ├── index.js │ │ └── package.json │ └── esm │ │ ├── .codesandbox │ │ ├── Dockerfile │ │ └── tasks.json │ │ ├── index.html │ │ ├── index.js │ │ └── package.json ├── create-react-app-example │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ ├── server.js │ ├── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── serviceWorker.js │ │ └── setupTests.js │ └── yarn.lock ├── custom-parsers │ ├── README.md │ ├── package.json │ ├── public │ │ ├── .gitignore │ │ └── index.html │ ├── src │ │ ├── client1.js │ │ ├── client2.js │ │ ├── client3.js │ │ ├── client4.js │ │ ├── custom-parser.js │ │ └── server.js │ └── support │ │ └── webpack.config.js ├── es-modules │ ├── README.md │ ├── client.js │ ├── package.json │ └── server.js ├── expo-example │ ├── .gitignore │ ├── App.js │ ├── app.json │ ├── assets │ │ ├── adaptive-icon.png │ │ ├── favicon.png │ │ ├── icon.png │ │ └── splash.png │ ├── babel.config.js │ ├── package.json │ ├── server │ │ ├── index.js │ │ └── package.json │ └── socket.js ├── express-session-example │ ├── README.md │ ├── assets │ │ └── demo.gif │ ├── cjs │ │ ├── index.html │ │ ├── index.js │ │ └── package.json │ ├── esm │ │ ├── index.html │ │ ├── index.js │ │ └── package.json │ └── ts │ │ ├── index.html │ │ ├── index.ts │ │ ├── package.json │ │ └── tsconfig.json ├── nestjs-example │ ├── .eslintrc.js │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── nest-cli.json │ ├── package.json │ ├── src │ │ ├── app.controller.spec.ts │ │ ├── app.controller.ts │ │ ├── app.module.ts │ │ ├── app.service.ts │ │ ├── events │ │ │ ├── events.gateway.ts │ │ │ └── events.module.ts │ │ └── main.ts │ ├── test │ │ ├── app.e2e-spec.ts │ │ └── jest-e2e.json │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── views │ │ └── index.hbs ├── nextjs-app-router │ ├── .gitignore │ ├── README.md │ ├── jsconfig.json │ ├── next.config.mjs │ ├── package.json │ ├── public │ │ ├── next.svg │ │ └── vercel.svg │ ├── server.js │ └── src │ │ ├── app │ │ ├── favicon.ico │ │ ├── globals.css │ │ ├── layout.js │ │ ├── page.js │ │ └── page.module.css │ │ └── socket.js ├── nextjs-pages-router │ ├── .gitignore │ ├── README.md │ ├── jsconfig.json │ ├── next.config.mjs │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── next.svg │ │ └── vercel.svg │ ├── server.js │ └── src │ │ ├── pages │ │ ├── _app.js │ │ ├── _document.js │ │ ├── api │ │ │ └── hello.js │ │ └── index.js │ │ ├── socket.js │ │ └── styles │ │ ├── Home.module.css │ │ └── globals.css ├── nuxt-example │ ├── .gitignore │ ├── README.md │ ├── app.vue │ ├── components │ │ ├── Connection.client.vue │ │ └── socket.ts │ ├── nuxt.config.ts │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── server │ │ ├── plugins │ │ │ └── socket.io.ts │ │ └── tsconfig.json │ └── tsconfig.json ├── nwjs-example │ ├── README.md │ ├── index.html │ ├── index.js │ ├── package.json │ └── server │ │ ├── index.js │ │ └── package.json ├── passport-example │ ├── README.md │ ├── assets │ │ └── passport_example.gif │ ├── cjs │ │ ├── index.html │ │ ├── index.js │ │ ├── login.html │ │ └── package.json │ ├── esm │ │ ├── index.html │ │ ├── index.js │ │ ├── login.html │ │ └── package.json │ └── ts │ │ ├── index.html │ │ ├── index.ts │ │ ├── login.html │ │ ├── package.json │ │ └── tsconfig.json ├── passport-jwt-example │ ├── README.md │ ├── assets │ │ └── passport_example.gif │ ├── cjs │ │ ├── index.html │ │ ├── index.js │ │ └── package.json │ ├── esm │ │ ├── index.html │ │ ├── index.js │ │ └── package.json │ └── ts │ │ ├── index.html │ │ ├── index.ts │ │ ├── package.json │ │ └── tsconfig.json ├── postgres-adapter-example │ ├── README.md │ ├── client.js │ ├── cluster.js │ ├── compose.yaml │ ├── package.json │ └── server.js ├── private-messaging │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── fonts │ │ │ └── Lato-Regular.ttf │ │ └── index.html │ ├── server │ │ ├── cluster.js │ │ ├── docker-compose.yml │ │ ├── index.js │ │ ├── messageStore.js │ │ ├── package.json │ │ └── sessionStore.js │ └── src │ │ ├── App.vue │ │ ├── components │ │ ├── Chat.vue │ │ ├── MessagePanel.vue │ │ ├── SelectUsername.vue │ │ ├── StatusIcon.vue │ │ └── User.vue │ │ ├── main.js │ │ └── socket.js ├── rollup-server-bundle │ ├── .gitignore │ ├── index.js │ ├── package.json │ └── rollup.config.js ├── tweet-stream │ ├── index.js │ └── package.json ├── typescript-client-example │ ├── cjs │ │ ├── client.ts │ │ ├── package.json │ │ └── tsconfig.json │ └── esm │ │ ├── client.ts │ │ ├── package.json │ │ └── tsconfig.json ├── typescript-example │ ├── cjs │ │ ├── client.ts │ │ ├── package.json │ │ ├── server.ts │ │ └── tsconfig.json │ └── esm │ │ ├── client.ts │ │ ├── package.json │ │ ├── server.ts │ │ └── tsconfig.json ├── webpack-build-server │ ├── README.md │ ├── index.js │ ├── package.json │ └── webpack.config.js ├── webpack-build │ ├── README.md │ ├── index.html │ ├── index.js │ ├── package.json │ └── webpack.config.js ├── webtransport │ ├── .gitignore │ ├── README.md │ ├── generate_cert.sh │ ├── index.html │ ├── index.js │ ├── open_chrome.sh │ └── package.json └── whiteboard │ ├── README.md │ ├── index.js │ ├── package.json │ └── public │ ├── index.html │ ├── main.js │ └── style.css ├── package-lock.json ├── package.json └── packages ├── engine.io-client ├── .gitignore ├── .prettierignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dist │ ├── engine.io.esm.min.js │ ├── engine.io.esm.min.js.map │ ├── engine.io.js │ ├── engine.io.js.map │ ├── engine.io.min.js │ └── engine.io.min.js.map ├── lib │ ├── browser-entrypoint.ts │ ├── contrib │ │ ├── has-cors.ts │ │ ├── parseqs.ts │ │ └── parseuri.ts │ ├── globals.node.ts │ ├── globals.ts │ ├── index.ts │ ├── socket.ts │ ├── transport.ts │ ├── transports │ │ ├── index.ts │ │ ├── polling-fetch.ts │ │ ├── polling-xhr.node.ts │ │ ├── polling-xhr.ts │ │ ├── polling.ts │ │ ├── websocket.node.ts │ │ ├── websocket.ts │ │ └── webtransport.ts │ └── util.ts ├── package.json ├── postcompile.sh ├── support │ ├── bundle-size.js │ ├── package.cjs.json │ ├── package.esm.json │ ├── prod.config.js │ ├── rollup.config.esm.js │ ├── rollup.config.umd.js │ └── webpack.config.js ├── test │ ├── arraybuffer │ │ ├── index.js │ │ ├── polling.js │ │ └── ws.js │ ├── binary-fallback.js │ ├── blob │ │ ├── index.js │ │ ├── polling.js │ │ └── ws.js │ ├── connection.js │ ├── engine.io-client.js │ ├── fixtures │ │ ├── no-unref.js │ │ ├── unref-polling-only.js │ │ ├── unref-websocket-only.js │ │ └── unref.js │ ├── index.js │ ├── node.js │ ├── parseuri.js │ ├── socket.js │ ├── support │ │ ├── env.js │ │ ├── hooks.js │ │ ├── public │ │ │ └── worker.js │ │ └── server.js │ ├── transport.js │ ├── util-wt.mjs │ ├── util.js │ ├── webtransport.mjs │ └── xmlhttprequest.js ├── tsconfig.esm.json └── tsconfig.json ├── engine.io-parser ├── .prettierignore ├── CHANGELOG.md ├── LICENSE ├── Readme.md ├── benchmarks │ ├── index.js │ └── results.md ├── lib │ ├── commons.ts │ ├── contrib │ │ └── base64-arraybuffer.ts │ ├── decodePacket.browser.ts │ ├── decodePacket.ts │ ├── encodePacket.browser.ts │ ├── encodePacket.ts │ └── index.ts ├── package.json ├── postcompile.sh ├── support │ ├── package.cjs.json │ └── package.esm.json ├── test.js ├── test │ ├── browser.ts │ ├── index.ts │ ├── node.ts │ └── util.ts ├── tsconfig.esm.json ├── tsconfig.json └── zuul.config.js ├── engine.io ├── .eslintrc.json ├── .prettierignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples │ ├── esm-import │ │ ├── README.md │ │ ├── index.js │ │ └── package.json │ ├── latency │ │ ├── README.md │ │ ├── index.html │ │ ├── index.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── public │ │ │ ├── index.js │ │ │ └── style.css │ ├── memory-usage-webtransport │ │ ├── .gitignore │ │ ├── client.js │ │ ├── generate_cert.sh │ │ ├── package-lock.json │ │ ├── package.json │ │ └── server.js │ └── memory-usage │ │ ├── .gitignore │ │ ├── client.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── server.js ├── lib │ ├── contrib │ │ └── types.cookie.ts │ ├── engine.io.ts │ ├── parser-v3 │ │ ├── index.ts │ │ └── utf8.ts │ ├── server.ts │ ├── socket.ts │ ├── transport.ts │ ├── transports-uws │ │ ├── index.ts │ │ ├── polling.ts │ │ └── websocket.ts │ ├── transports │ │ ├── index.ts │ │ ├── polling-jsonp.ts │ │ ├── polling.ts │ │ ├── websocket.ts │ │ └── webtransport.ts │ └── userver.ts ├── package.json ├── test │ ├── .eslintrc.json │ ├── common.js │ ├── engine.io.js │ ├── fixtures │ │ ├── ca.crt │ │ ├── ca.key │ │ ├── ca.key.org │ │ ├── client.crt │ │ ├── client.csr │ │ ├── client.key │ │ ├── client.key.orig │ │ ├── client.pfx │ │ ├── server-close-upgraded.js │ │ ├── server-close-upgrading.js │ │ ├── server-close.js │ │ ├── server.crt │ │ ├── server.csr │ │ ├── server.key │ │ └── server.key.orig │ ├── middlewares.js │ ├── parser.js │ ├── server.js │ ├── util.mjs │ └── webtransport.mjs ├── tsconfig.json └── wrapper.mjs ├── socket.io-adapter ├── CHANGELOG.md ├── LICENSE ├── Readme.md ├── lib │ ├── cluster-adapter.ts │ ├── contrib │ │ └── yeast.ts │ ├── in-memory-adapter.ts │ └── index.ts ├── package.json ├── test │ ├── cluster-adapter.ts │ ├── index.ts │ └── util.ts └── tsconfig.json ├── socket.io-client ├── .prettierignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── babel.config.js ├── dist │ ├── socket.io.esm.min.js │ ├── socket.io.esm.min.js.map │ ├── socket.io.js │ ├── socket.io.js.map │ ├── socket.io.min.js │ ├── socket.io.min.js.map │ ├── socket.io.msgpack.min.js │ └── socket.io.msgpack.min.js.map ├── docs │ └── README.md ├── lib │ ├── browser-entrypoint.ts │ ├── contrib │ │ └── backo2.ts │ ├── index.ts │ ├── manager.ts │ ├── on.ts │ ├── socket.ts │ └── url.ts ├── package.json ├── postcompile.sh ├── support │ ├── bundle-size.js │ ├── package.esm.json │ ├── rollup.config.esm.js │ ├── rollup.config.umd.js │ └── rollup.config.umd.msgpack.js ├── test │ ├── .eslintrc.json │ ├── browser-runner.ts │ ├── connection-state-recovery.ts │ ├── connection.ts │ ├── fixtures │ │ ├── no-unref.ts │ │ ├── unref-during-reconnection.ts │ │ ├── unref-polling-only.ts │ │ ├── unref-websocket-only.ts │ │ └── unref.ts │ ├── index.ts │ ├── node.ts │ ├── retry.ts │ ├── socket.ts │ ├── support │ │ ├── hooks.ts │ │ ├── server.ts │ │ └── util.ts │ ├── typed-events.test-d.ts │ └── url.ts ├── tsconfig.esm.json ├── tsconfig.json └── wdio.conf.js ├── socket.io-cluster-engine ├── CHANGELOG.md ├── LICENSE ├── README.md ├── compose.yaml ├── lib │ ├── cluster.ts │ ├── engine.ts │ ├── index.ts │ └── redis.ts ├── package.json ├── test │ ├── cluster.ts │ ├── in-memory.ts │ ├── redis.ts │ ├── util.ts │ └── worker.js └── tsconfig.json ├── socket.io-component-emitter ├── History.md ├── LICENSE ├── Readme.md ├── component.json ├── lib │ ├── cjs │ │ ├── index.d.ts │ │ ├── index.js │ │ └── package.json │ └── esm │ │ ├── index.d.ts │ │ ├── index.js │ │ └── package.json ├── package.json └── test │ └── emitter.js ├── socket.io-parser ├── CHANGELOG.md ├── LICENSE ├── Readme.md ├── babel.config.js ├── bench │ ├── index.js │ └── results.md ├── lib │ ├── binary.ts │ ├── index.ts │ └── is-binary.ts ├── package.json ├── postcompile.sh ├── support │ ├── package.cjs.json │ └── package.esm.json ├── test │ ├── arraybuffer.js │ ├── blob.js │ ├── buffer.js │ ├── helpers.js │ ├── index.js │ ├── parser.js │ └── support │ │ └── env.js ├── tsconfig.esm.json ├── tsconfig.json └── wdio.conf.js └── socket.io ├── CHANGELOG.md ├── LICENSE ├── Readme.md ├── client-dist ├── socket.io.esm.min.js ├── socket.io.esm.min.js.map ├── socket.io.js ├── socket.io.js.map ├── socket.io.min.js ├── socket.io.min.js.map ├── socket.io.msgpack.min.js └── socket.io.msgpack.min.js.map ├── lib ├── broadcast-operator.ts ├── client.ts ├── index.ts ├── namespace.ts ├── parent-namespace.ts ├── socket-types.ts ├── socket.ts ├── typed-events.ts └── uws.ts ├── package.json ├── test ├── close.ts ├── connection-state-recovery.ts ├── fixtures │ ├── big.jpg │ ├── big.json │ └── server-close.ts ├── handshake.ts ├── index.ts ├── messaging-many.ts ├── middleware.ts ├── namespaces.ts ├── server-attachment.ts ├── socket-middleware.ts ├── socket-timeout.ts ├── socket.io.test-d.ts ├── socket.ts ├── support │ ├── doge.jpg │ ├── expectjs.d.ts │ └── util.ts ├── utility-methods.ts ├── uws.ts └── v2-compatibility.ts ├── tsconfig.json └── wrapper.mjs /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask a Question 4 | url: https://github.com/socketio/socket.io/discussions/new?category=q-a 5 | about: Ask the community for help 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'enhancement' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | ### The kind of change this PR does introduce 3 | 4 | * [x] a bug fix 5 | * [ ] a new feature 6 | * [ ] an update to the documentation 7 | * [ ] a code change that improves performance 8 | * [ ] other 9 | 10 | ### Current behavior 11 | 12 | 13 | ### New behavior 14 | 15 | 16 | ### Other information (e.g. related issues) 17 | 18 | 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | lib-cov 3 | *.seed 4 | *.log 5 | *.csv 6 | *.dat 7 | *.out 8 | *.pid 9 | benchmarks/*.png 10 | node_modules 11 | coverage 12 | .idea 13 | .nyc_output 14 | dist/ 15 | build/ 16 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | 2 | The documentation has been moved to the website [here](https://socket.io/docs/). 3 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v3-test-suite/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v3-test-suite/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8" /> 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 | 7 | <title>Test suite for the Engine.IO protocol</title> 8 | <link rel="stylesheet" href="https://unpkg.com/mocha@9/mocha.css" /> 9 | </head> 10 | <body> 11 | 12 | <div id="mocha"></div> 13 | 14 | <script src="https://unpkg.com/mocha@9/mocha.js"></script> 15 | <script src="https://unpkg.com/chai@4/chai.js" ></script> 16 | <script src="https://unpkg.com/chai-string@1/chai-string.js" ></script> 17 | 18 | <script class="mocha-init"> 19 | mocha.setup("bdd"); 20 | mocha.checkLeaks(); 21 | </script> 22 | 23 | <script type="module" src="test-suite.js"></script> 24 | 25 | <script class="mocha-exec"> 26 | mocha.run(); 27 | </script> 28 | 29 | </body> 30 | </html> 31 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v3-test-suite/node-imports.js: -------------------------------------------------------------------------------- 1 | import fetch from "node-fetch"; 2 | import { WebSocket } from "ws"; 3 | import chai from "chai"; 4 | import chaiString from "chai-string"; 5 | 6 | chai.use(chaiString); 7 | 8 | globalThis.fetch = fetch; 9 | globalThis.WebSocket = WebSocket; 10 | globalThis.chai = chai; 11 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v3-test-suite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine.io-protocol-test-suite", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "format": "prettier -w *.js", 8 | "test": "mocha test-suite.js" 9 | }, 10 | "devDependencies": { 11 | "chai": "^4.3.6", 12 | "chai-string": "^1.5.0", 13 | "mocha": "^9.2.1", 14 | "node-fetch": "^3.2.0", 15 | "prettier": "^2.5.1", 16 | "ws": "^8.5.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v4-test-suite/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v4-test-suite/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8" /> 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 | 7 | <title>Test suite for the Engine.IO protocol</title> 8 | <link rel="stylesheet" href="https://unpkg.com/mocha@9/mocha.css" /> 9 | </head> 10 | <body> 11 | 12 | <div id="mocha"></div> 13 | 14 | <script src="https://unpkg.com/mocha@9/mocha.js"></script> 15 | <script src="https://unpkg.com/chai@4/chai.js" ></script> 16 | <script src="https://unpkg.com/chai-string@1/chai-string.js" ></script> 17 | 18 | <script class="mocha-init"> 19 | mocha.setup("bdd"); 20 | mocha.checkLeaks(); 21 | </script> 22 | 23 | <script type="module" src="test-suite.js"></script> 24 | 25 | <script class="mocha-exec"> 26 | mocha.run(); 27 | </script> 28 | 29 | </body> 30 | </html> 31 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v4-test-suite/node-imports.js: -------------------------------------------------------------------------------- 1 | import fetch from "node-fetch"; 2 | import { WebSocket } from "ws"; 3 | import chai from "chai"; 4 | import chaiString from "chai-string"; 5 | 6 | chai.use(chaiString); 7 | 8 | globalThis.fetch = fetch; 9 | globalThis.WebSocket = WebSocket; 10 | globalThis.chai = chai; 11 | -------------------------------------------------------------------------------- /docs/engine.io-protocol/v4-test-suite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine.io-protocol-test-suite", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "format": "prettier -w *.js", 8 | "test": "mocha test-suite.js" 9 | }, 10 | "devDependencies": { 11 | "chai": "^4.3.6", 12 | "chai-string": "^1.5.0", 13 | "mocha": "^9.2.1", 14 | "node-fetch": "^3.2.0", 15 | "prettier": "^2.5.1", 16 | "ws": "^8.5.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/socket.io-protocol/v5-test-suite/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /docs/socket.io-protocol/v5-test-suite/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8" /> 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 | 7 | <title>Test suite for the Socket.IO protocol</title> 8 | <link rel="stylesheet" href="https://unpkg.com/mocha@9/mocha.css" /> 9 | </head> 10 | <body> 11 | 12 | <div id="mocha"></div> 13 | 14 | <script src="https://unpkg.com/mocha@9/mocha.js"></script> 15 | <script src="https://unpkg.com/chai@4/chai.js" ></script> 16 | <script src="https://unpkg.com/chai-string@1/chai-string.js" ></script> 17 | 18 | <script class="mocha-init"> 19 | mocha.setup("bdd"); 20 | mocha.checkLeaks(); 21 | </script> 22 | 23 | <script type="module" src="test-suite.js"></script> 24 | 25 | <script class="mocha-exec"> 26 | mocha.run(); 27 | </script> 28 | 29 | </body> 30 | </html> 31 | -------------------------------------------------------------------------------- /docs/socket.io-protocol/v5-test-suite/node-imports.js: -------------------------------------------------------------------------------- 1 | import fetch from "node-fetch"; 2 | import { WebSocket } from "ws"; 3 | import chai from "chai"; 4 | import chaiString from "chai-string"; 5 | 6 | chai.use(chaiString); 7 | 8 | globalThis.fetch = fetch; 9 | globalThis.WebSocket = WebSocket; 10 | globalThis.chai = chai; 11 | -------------------------------------------------------------------------------- /docs/socket.io-protocol/v5-test-suite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-protocol-test-suite", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "format": "prettier -w *.js", 8 | "test": "mocha test-suite.js" 9 | }, 10 | "devDependencies": { 11 | "chai": "^4.3.6", 12 | "chai-string": "^1.5.0", 13 | "mocha": "^9.2.1", 14 | "node-fetch": "^3.2.0", 15 | "prettier": "^2.5.1", 16 | "ws": "^8.5.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Cocoapods 1.15 introduced a bug which break the build. We will remove the upper 7 | # bound in the template on Cocoapods with next React Native release. 8 | gem 'cocoapods', '>= 1.13', '< 1.15' 9 | gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' 10 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: import explicitly to use the types shipped with jest. 10 | import {it} from '@jest/globals'; 11 | 12 | // Note: test renderer must be required after react-native. 13 | import renderer from 'react-test-renderer'; 14 | 15 | it('renders correctly', () => { 16 | renderer.create(<App />); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/debug.keystore -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 | xmlns:tools="http://schemas.android.com/tools"> 4 | 5 | <application 6 | android:usesCleartextTraffic="true" 7 | tools:targetApi="28" 8 | tools:ignore="GoogleAppIndexingWarning"/> 9 | </manifest> 10 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | <resources> 2 | <string name="app_name">ReactNativeExample</string> 3 | </resources> 4 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | <resources> 2 | 3 | <!-- Base application theme. --> 4 | <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> 5 | <!-- Customize your theme here. --> 6 | <item name="android:editTextBackground">@drawable/rn_edit_text_material</item> 7 | </style> 8 | 9 | </resources> 10 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 21 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "25.1.8937393" 8 | kotlinVersion = "1.8.0" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | apply plugin: "com.facebook.react.rootproject" 22 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/ReactNativeExample/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'ReactNativeExample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactNativeExample", 3 | "displayName": "ReactNativeExample" 4 | } 5 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/ios/ReactNativeExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import <RCTAppDelegate.h> 2 | #import <UIKit/UIKit.h> 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/ios/ReactNativeExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/ios/ReactNativeExample/main.m: -------------------------------------------------------------------------------- 1 | #import <UIKit/UIKit.h> 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/ios/ReactNativeExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>en</string> 7 | <key>CFBundleExecutable</key> 8 | <string>$(EXECUTABLE_NAME)</string> 9 | <key>CFBundleIdentifier</key> 10 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 11 | <key>CFBundleInfoDictionaryVersion</key> 12 | <string>6.0</string> 13 | <key>CFBundleName</key> 14 | <string>$(PRODUCT_NAME)</string> 15 | <key>CFBundlePackageType</key> 16 | <string>BNDL</string> 17 | <key>CFBundleShortVersionString</key> 18 | <string>1.0</string> 19 | <key>CFBundleSignature</key> 20 | <string>????</string> 21 | <key>CFBundleVersion</key> 22 | <string>1</string> 23 | </dict> 24 | </plist> 25 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://facebook.github.io/metro/docs/configuration 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/server/index.js: -------------------------------------------------------------------------------- 1 | import { Server } from 'socket.io'; 2 | 3 | const io = new Server(); 4 | 5 | io.on('connection', (socket) => { 6 | console.log(`connect: ${socket.id}`, socket.request.headers); 7 | 8 | socket.on('disconnect', () => { 9 | console.log(`disconnect: ${socket.id}`); 10 | }); 11 | }); 12 | 13 | io.listen(3000); 14 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "socket.io": "^4.7.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/socket.js: -------------------------------------------------------------------------------- 1 | import { io } from 'socket.io-client'; 2 | 3 | export const socket = io('http://192.168.0.10:3000'); // use the IP address of your machine 4 | -------------------------------------------------------------------------------- /examples/ReactNativeExample/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /examples/angular-todomvc/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /examples/angular-todomvc/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/angular-todomvc/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /examples/angular-todomvc/assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/angular-todomvc/assets/demo.gif -------------------------------------------------------------------------------- /examples/angular-todomvc/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', async () => { 12 | await page.navigateTo(); 13 | expect(await page.getTitleText()).toEqual('angular-todomvc app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /examples/angular-todomvc/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | async navigateTo(): Promise<unknown> { 5 | return browser.get(browser.baseUrl); 6 | } 7 | 8 | async getTitleText(): Promise<string> { 9 | return element(by.css('app-root .content span')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/angular-todomvc/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../out-tsc/e2e", 6 | "module": "commonjs", 7 | "target": "es2018", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/angular-todomvc/server.ts: -------------------------------------------------------------------------------- 1 | import { Server } from "socket.io"; 2 | 3 | const io = new Server(8080, { 4 | cors: { 5 | origin: "http://localhost:4200", 6 | methods: ["GET", "POST"] 7 | } 8 | }); 9 | 10 | interface Todo { 11 | completed: boolean; 12 | editing: boolean; 13 | title: string; 14 | } 15 | 16 | let todos: Array<Todo> = []; 17 | 18 | io.on("connection", (socket) => { 19 | socket.emit("todos", todos); 20 | 21 | // note: we could also create a CRUD (create/read/update/delete) service for the todo list 22 | socket.on("update-store", (updatedTodos) => { 23 | // store it locally 24 | todos = updatedTodos; 25 | // broadcast to everyone but the sender 26 | socket.broadcast.emit("todos", todos); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /examples/angular-todomvc/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/angular-todomvc/src/app/app.component.css -------------------------------------------------------------------------------- /examples/angular-todomvc/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppComponent } from './app.component'; 5 | import { RemoteTodoStore } from './store'; 6 | import { FormsModule } from "@angular/forms"; 7 | 8 | @NgModule({ 9 | declarations: [ 10 | AppComponent 11 | ], 12 | imports: [ 13 | BrowserModule, 14 | FormsModule 15 | ], 16 | providers: [RemoteTodoStore], 17 | bootstrap: [AppComponent] 18 | }) 19 | export class AppModule { } 20 | -------------------------------------------------------------------------------- /examples/angular-todomvc/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/angular-todomvc/src/assets/.gitkeep -------------------------------------------------------------------------------- /examples/angular-todomvc/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /examples/angular-todomvc/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /examples/angular-todomvc/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/angular-todomvc/src/favicon.ico -------------------------------------------------------------------------------- /examples/angular-todomvc/src/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8"> 5 | <title>Angular Todo MVC</title> 6 | <base href="/"> 7 | <meta name="viewport" content="width=device-width, initial-scale=1"> 8 | <link rel="icon" type="image/x-icon" href="favicon.ico"> 9 | </head> 10 | <body> 11 | <app-root></app-root> 12 | </body> 13 | </html> 14 | -------------------------------------------------------------------------------- /examples/angular-todomvc/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /examples/angular-todomvc/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | <T>(id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /examples/angular-todomvc/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/angular-todomvc/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "sourceMap": true, 12 | "declaration": false, 13 | "downlevelIteration": true, 14 | "experimentalDecorators": true, 15 | "moduleResolution": "node", 16 | "importHelpers": true, 17 | "target": "es2015", 18 | "module": "es2020", 19 | "lib": [ 20 | "es2018", 21 | "dom" 22 | ] 23 | }, 24 | "angularCompilerOptions": { 25 | "strictInjectionParameters": true, 26 | "strictInputAccessModifiers": true, 27 | "strictTemplates": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/angular-todomvc/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/basic-crud-application/angular-client/src/app/app.component.css -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | 4 | import { routes } from './app.routes'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [provideRouter(routes)] 8 | }; 9 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const routes: Routes = []; 4 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/basic-crud-application/angular-client/src/assets/.gitkeep -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/environments/environment.development.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | serverUrl: "http://localhost:3000" 3 | }; 4 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | serverUrl: "https://my-custom-domain.com" 3 | }; 4 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/basic-crud-application/angular-client/src/favicon.ico -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8"> 5 | <title>AngularClient</title> 6 | <base href="/"> 7 | <meta name="viewport" content="width=device-width, initial-scale=1"> 8 | <link rel="icon" type="image/x-icon" href="favicon.ico"> 9 | </head> 10 | <body> 11 | <app-root></app-root> 12 | </body> 13 | </html> 14 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig) 6 | .catch((err) => console.error(err)); 7 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/basic-crud-application/angular-client/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server-postgres-cluster/README.md: -------------------------------------------------------------------------------- 1 | 2 | A basic TODO project. 3 | 4 | | Characteristic | | 5 | |----------------|-------------------------------------------------------------------------------------------| 6 | | Language | plain JavaScript | 7 | | Database | Postgres, with the [Postgres adapter](https://socket.io/docs/v4/postgres-adapter/) | 8 | | Cluster? | Yes, with the [`@socket.io/sticky`](https://github.com/socketio/socket.io-sticky) module) | 9 | 10 | ## Usage 11 | 12 | ``` 13 | $ docker-compose up -d 14 | $ npm install 15 | $ npm start 16 | ``` 17 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server-postgres-cluster/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | postgres: 5 | image: postgres:12 6 | ports: 7 | - "5432:5432" 8 | environment: 9 | POSTGRES_PASSWORD: "changeit" 10 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server-postgres-cluster/lib/cluster.js: -------------------------------------------------------------------------------- 1 | import cluster from "cluster"; 2 | import { createServer } from "http"; 3 | import { setupMaster } from "@socket.io/sticky"; 4 | import { cpus } from "os"; 5 | 6 | if (cluster.isMaster) { 7 | console.log(`Master ${process.pid} is running`); 8 | const httpServer = createServer(); 9 | 10 | setupMaster(httpServer, { 11 | loadBalancingMethod: "least-connection", 12 | }); 13 | 14 | httpServer.listen(3000); 15 | 16 | for (let i = 0; i < cpus().length; i++) { 17 | cluster.fork(); 18 | } 19 | 20 | cluster.on("exit", (worker) => { 21 | console.log(`Worker ${worker.process.pid} died`); 22 | cluster.fork(); 23 | }); 24 | } else { 25 | console.log(`Worker ${process.pid} started`); 26 | 27 | import("./index.js"); 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server-postgres-cluster/lib/util.js: -------------------------------------------------------------------------------- 1 | export const Errors = { 2 | ENTITY_NOT_FOUND: "entity not found", 3 | INVALID_PAYLOAD: "invalid payload", 4 | }; 5 | 6 | const errorValues = Object.values(Errors); 7 | 8 | export function sanitizeErrorMessage(message) { 9 | if (typeof message === "string" && errorValues.includes(message)) { 10 | return message; 11 | } else { 12 | return "an unknown error has occurred"; 13 | } 14 | } 15 | 16 | export function mapErrorDetails(details) { 17 | return details.map((item) => ({ 18 | message: item.message, 19 | path: item.path, 20 | type: item.type, 21 | })); 22 | } 23 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server/lib/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer } from "http"; 2 | import { createApplication } from "./app"; 3 | import { InMemoryTodoRepository } from "./todo-management/todo.repository"; 4 | 5 | const httpServer = createServer(); 6 | 7 | createApplication( 8 | httpServer, 9 | { 10 | todoRepository: new InMemoryTodoRepository(), 11 | }, 12 | { 13 | cors: { 14 | origin: ["http://localhost:4200"], 15 | }, 16 | } 17 | ); 18 | 19 | httpServer.listen(3000); 20 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server/lib/util.ts: -------------------------------------------------------------------------------- 1 | import { ValidationErrorItem } from "joi"; 2 | 3 | export enum Errors { 4 | ENTITY_NOT_FOUND = "entity not found", 5 | INVALID_PAYLOAD = "invalid payload", 6 | } 7 | 8 | const errorValues: string[] = Object.values(Errors); 9 | 10 | export function sanitizeErrorMessage(message: any) { 11 | if (typeof message === "string" && errorValues.includes(message)) { 12 | return message; 13 | } else { 14 | return "an unknown error has occurred"; 15 | } 16 | } 17 | 18 | export function mapErrorDetails(details: ValidationErrorItem[]) { 19 | return details.map((item) => ({ 20 | message: item.message, 21 | path: item.path, 22 | type: item.type, 23 | })); 24 | } 25 | -------------------------------------------------------------------------------- /examples/basic-crud-application/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "module": "commonjs", 5 | "target": "es2017", 6 | "strict": true 7 | }, 8 | "include": [ 9 | "./lib/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/README.md: -------------------------------------------------------------------------------- 1 | # vue-client 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": [ 9 | "src/*" 10 | ] 11 | }, 12 | "lib": [ 13 | "esnext", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/basic-crud-application/vue-client/public/favicon.ico -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/public/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang=""> 3 | <head> 4 | <meta charset="utf-8"> 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 | <meta name="viewport" content="width=device-width,initial-scale=1.0"> 7 | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> 8 | <link href="styles.css" rel="stylesheet" type="text/css" /> 9 | <title><%= htmlWebpackPlugin.options.title %></title> 10 | </head> 11 | <body> 12 | <noscript> 13 | <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> 14 | </noscript> 15 | <div id="app"></div> 16 | <!-- built files will be auto injected --> 17 | </body> 18 | </html> 19 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/basic-crud-application/vue-client/src/assets/logo.png -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import { createPinia } from "pinia"; 3 | import App from "./App.vue"; 4 | 5 | const pinia = createPinia(); 6 | const app = createApp(App); 7 | 8 | app.use(pinia); 9 | app.mount("#app"); 10 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/src/socket.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | // "undefined" means the URL will be computed from the `window.location` object 4 | const URL = 5 | process.env.NODE_ENV === "production" ? undefined : "http://localhost:3000"; 6 | 7 | export const socket = io(URL); 8 | -------------------------------------------------------------------------------- /examples/basic-crud-application/vue-client/vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | module.exports = defineConfig({ 3 | transpileDependencies: true 4 | }) 5 | -------------------------------------------------------------------------------- /examples/basic-websocket-client/README.md: -------------------------------------------------------------------------------- 1 | # Basic Socket.IO client 2 | 3 | Please check the associated guide: https://socket.io/how-to/build-a-basic-client 4 | 5 | Content: 6 | 7 | ``` 8 | ├── bundle 9 | │ └── socket.io.min.js 10 | ├── src 11 | │ └── index.js 12 | ├── test 13 | │ └── index.js 14 | ├── check-bundle-size.js 15 | ├── package.json 16 | ├── README.md 17 | └── rollup.config.js 18 | ``` 19 | -------------------------------------------------------------------------------- /examples/basic-websocket-client/check-bundle-size.js: -------------------------------------------------------------------------------- 1 | import { rollup } from "rollup"; 2 | import terser from "@rollup/plugin-terser"; 3 | import { brotliCompressSync } from "node:zlib"; 4 | 5 | const rollupBuild = await rollup({ 6 | input: "./src/index.js" 7 | }); 8 | 9 | const rollupOutput = await rollupBuild.generate({ 10 | format: "esm", 11 | plugins: [terser()], 12 | }); 13 | 14 | const bundleAsString = rollupOutput.output[0].code; 15 | const brotliedBundle = brotliCompressSync(Buffer.from(bundleAsString)); 16 | 17 | console.log(`Bundle size: ${brotliedBundle.length} B`); 18 | -------------------------------------------------------------------------------- /examples/basic-websocket-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "devDependencies": { 4 | "@rollup/plugin-terser": "^0.4.0", 5 | "chai": "^4.3.7", 6 | "mocha": "^10.2.0", 7 | "prettier": "^2.8.4", 8 | "rollup": "^3.20.2", 9 | "socket.io": "^4.6.1", 10 | "ws": "^8.13.0" 11 | }, 12 | "scripts": { 13 | "bundle": "rollup -c", 14 | "check-bundle-size": "node check-bundle-size.js", 15 | "format": "prettier -w src/ test/", 16 | "test": "mocha" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/basic-websocket-client/rollup.config.js: -------------------------------------------------------------------------------- 1 | import terser from "@rollup/plugin-terser"; 2 | 3 | export default { 4 | input: "./src/index.js", 5 | output: { 6 | file: "./bundle/socket.io.min.js", 7 | format: "esm", 8 | plugins: [terser()], 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /examples/chat/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Socket.IO Chat 3 | 4 | A simple chat demo for Socket.IO 5 | 6 | ## How to use 7 | 8 | ``` 9 | $ npm i 10 | $ npm start 11 | ``` 12 | 13 | And point your browser to `http://localhost:3000`. Optionally, specify 14 | a port by supplying the `PORT` env variable. 15 | 16 | ## Features 17 | 18 | - Multiple users can join a chat room by each entering a unique username 19 | on website load. 20 | - Users can type chat messages to the chat room. 21 | - A notification is sent to all users when a user joins or leaves 22 | the chatroom. 23 | -------------------------------------------------------------------------------- /examples/chat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-chat", 3 | "version": "0.0.0", 4 | "description": "A simple chat client using socket.io", 5 | "main": "index.js", 6 | "author": "Grant Timmerman", 7 | "private": true, 8 | "license": "BSD", 9 | "dependencies": { 10 | "express": "~4.17.1", 11 | "socket.io": "^4.0.0" 12 | }, 13 | "scripts": { 14 | "start": "node index.js" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/chat/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO Chat Example</title> 6 | <link rel="stylesheet" href="style.css"> 7 | </head> 8 | <body> 9 | <ul class="pages"> 10 | <li class="chat page"> 11 | <div class="chatArea"> 12 | <ul class="messages"></ul> 13 | </div> 14 | <input class="inputMessage" placeholder="Type here..."/> 15 | </li> 16 | <li class="login page"> 17 | <div class="form"> 18 | <h3 class="title">What's your nickname?</h3> 19 | <input class="usernameInput" type="text" maxlength="14" /> 20 | </div> 21 | </li> 22 | </ul> 23 | 24 | <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> 25 | <script src="/socket.io/socket.io.js"></script> 26 | <script src="/main.js"></script> 27 | </body> 28 | </html> -------------------------------------------------------------------------------- /examples/cluster-engine-node-cluster/README.md: -------------------------------------------------------------------------------- 1 | # Example with `@socket.io/cluster-engine` and Node.js cluster 2 | 3 | ## How to use 4 | 5 | ```bash 6 | # run the server 7 | $ node server.js 8 | 9 | # run the client 10 | $ node client.js 11 | ``` 12 | 13 | ## Explanation 14 | 15 | The `server.js` script will create one Socket.IO server per core, each listening on the same port (`3000`). 16 | 17 | With the default engine (provided by the `engine.io` package), sticky sessions would be required, so that each HTTP request of the same Engine.IO session reaches the same worker. 18 | 19 | The `NodeClusterEngine` is a custom engine which takes care of the synchronization between the servers by using [the IPC channel](https://nodejs.org/api/cluster.html#workersendmessage-sendhandle-options-callback) and removes the need for sticky sessions when scaling horizontally. 20 | -------------------------------------------------------------------------------- /examples/cluster-engine-node-cluster/client.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const CLIENTS_COUNT = 3; 4 | 5 | for (let i = 0; i < CLIENTS_COUNT; i++) { 6 | const socket = io("ws://localhost:3000/", { 7 | // transports: ["polling"], 8 | // transports: ["websocket"], 9 | }); 10 | 11 | socket.on("connect", () => { 12 | console.log(`connected as ${socket.id}`); 13 | }); 14 | 15 | socket.on("disconnect", (reason) => { 16 | console.log(`disconnected due to ${reason}`); 17 | }); 18 | 19 | socket.on("hello", (socketId, workerId) => { 20 | console.log(`received "hello" from ${socketId} (worker: ${workerId})`); 21 | }); 22 | 23 | setInterval(() => { 24 | socket.emit("hello"); 25 | }, 2000); 26 | } 27 | -------------------------------------------------------------------------------- /examples/cluster-engine-node-cluster/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "cluster-engine-node-cluster", 4 | "version": "0.0.1", 5 | "type": "module", 6 | "dependencies": { 7 | "@socket.io/cluster-adapter": "^0.2.2", 8 | "@socket.io/cluster-engine": "^0.1.0", 9 | "socket.io": "^4.7.5", 10 | "socket.io-client": "^4.7.5" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/cluster-engine-redis/README.md: -------------------------------------------------------------------------------- 1 | # Example with `@socket.io/cluster-engine` and Redis 2 | 3 | ## How to use 4 | 5 | ```bash 6 | # start the redis server 7 | $ docker compose up -d 8 | 9 | # run the server 10 | $ node server.js 11 | 12 | # run the client 13 | $ node client.js 14 | ``` 15 | 16 | ## Explanation 17 | 18 | The `server.js` script will create 3 Socket.IO servers, each listening on a distinct port (`3001`, `3002` and `3003`), and a proxy server listening on port `3000` which randomly redirects to one of those servers. 19 | 20 | With the default engine (provided by the `engine.io` package), sticky sessions would be required, so that each HTTP request of the same Engine.IO session reaches the same server. 21 | 22 | The `RedisEngine` is a custom engine which takes care of the synchronization between the servers by using [Redis pub/sub](https://redis.io/docs/latest/develop/interact/pubsub/) and removes the need for sticky sessions when scaling horizontally. 23 | -------------------------------------------------------------------------------- /examples/cluster-engine-redis/client.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const CLIENTS_COUNT = 3; 4 | 5 | for (let i = 0; i < CLIENTS_COUNT; i++) { 6 | const socket = io("ws://localhost:3000/", { 7 | // transports: ["polling"], 8 | // transports: ["websocket"], 9 | }); 10 | 11 | socket.on("connect", () => { 12 | console.log(`connected as ${socket.id}`); 13 | }); 14 | 15 | socket.on("disconnect", (reason) => { 16 | console.log(`disconnected due to ${reason}`); 17 | }); 18 | 19 | socket.on("hello", (socketId, workerId) => { 20 | console.log(`received "hello" from ${socketId} (worker: ${workerId})`); 21 | }); 22 | 23 | setInterval(() => { 24 | socket.emit("hello"); 25 | }, 2000); 26 | } 27 | -------------------------------------------------------------------------------- /examples/cluster-engine-redis/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | redis: 3 | image: redis:7 4 | ports: 5 | - "6379:6379" 6 | -------------------------------------------------------------------------------- /examples/cluster-engine-redis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "cluster-engine-redis", 4 | "version": "0.0.1", 5 | "type": "module", 6 | "dependencies": { 7 | "@socket.io/cluster-engine": "^0.1.0", 8 | "@socket.io/redis-adapter": "^8.3.0", 9 | "http-proxy": "^1.18.1", 10 | "redis": "^4.6.15", 11 | "socket.io": "^4.7.5", 12 | "socket.io-client": "^4.7.5" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/cluster-haproxy/haproxy.cfg: -------------------------------------------------------------------------------- 1 | # Reference: http://blog.haproxy.com/2012/11/07/websockets-load-balancing-with-haproxy/ 2 | 3 | global 4 | daemon 5 | maxconn 4096 6 | nbproc 2 7 | 8 | defaults 9 | mode http 10 | balance roundrobin 11 | option http-server-close 12 | timeout connect 5s 13 | timeout client 30s 14 | timeout client-fin 30s 15 | timeout server 30s 16 | timeout tunnel 1h 17 | default-server inter 1s rise 2 fall 1 on-marked-down shutdown-sessions 18 | option forwardfor 19 | 20 | listen chat 21 | bind *:80 22 | default_backend nodes 23 | 24 | backend nodes 25 | option httpchk HEAD /health 26 | http-check expect status 200 27 | cookie serverid insert 28 | server john server-john:3000 cookie john check 29 | server paul server-paul:3000 cookie paul check 30 | server george server-george:3000 cookie george check 31 | server ringo server-ringo:3000 cookie ringo check 32 | -------------------------------------------------------------------------------- /examples/cluster-haproxy/server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install --prod 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 3000 15 | CMD [ "npm", "start" ] 16 | -------------------------------------------------------------------------------- /examples/cluster-haproxy/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-chat", 3 | "version": "0.0.0", 4 | "description": "A simple chat client using socket.io", 5 | "main": "index.js", 6 | "author": "Grant Timmerman", 7 | "private": true, 8 | "license": "BSD", 9 | "dependencies": { 10 | "express": "4.13.4", 11 | "socket.io": "^4.0.0", 12 | "socket.io-redis": "^6.0.1" 13 | }, 14 | "scripts": { 15 | "start": "node index.js" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/cluster-haproxy/server/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO Chat Example</title> 6 | <link rel="stylesheet" href="style.css"> 7 | </head> 8 | <body> 9 | <ul class="pages"> 10 | <li class="chat page"> 11 | <div class="chatArea"> 12 | <ul class="messages"></ul> 13 | </div> 14 | <input class="inputMessage" placeholder="Type here..."/> 15 | </li> 16 | <li class="login page"> 17 | <div class="form"> 18 | <h3 class="title">What's your nickname?</h3> 19 | <input class="usernameInput" type="text" maxlength="14" /> 20 | </div> 21 | </li> 22 | </ul> 23 | 24 | <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> 25 | <script src="/socket.io/socket.io.js"></script> 26 | <script src="/main.js"></script> 27 | </body> 28 | </html> -------------------------------------------------------------------------------- /examples/cluster-httpd/server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install --prod 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 3000 15 | CMD [ "npm", "start" ] 16 | -------------------------------------------------------------------------------- /examples/cluster-httpd/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-chat", 3 | "version": "0.0.0", 4 | "description": "A simple chat client using socket.io", 5 | "main": "index.js", 6 | "author": "Grant Timmerman", 7 | "private": true, 8 | "license": "BSD", 9 | "dependencies": { 10 | "express": "4.13.4", 11 | "socket.io": "^4.0.0", 12 | "socket.io-redis": "^6.0.1" 13 | }, 14 | "scripts": { 15 | "start": "node index.js" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/cluster-httpd/server/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO Chat Example</title> 6 | <link rel="stylesheet" href="style.css"> 7 | </head> 8 | <body> 9 | <ul class="pages"> 10 | <li class="chat page"> 11 | <div class="chatArea"> 12 | <ul class="messages"></ul> 13 | </div> 14 | <input class="inputMessage" placeholder="Type here..."/> 15 | </li> 16 | <li class="login page"> 17 | <div class="form"> 18 | <h3 class="title">What's your nickname?</h3> 19 | <input class="usernameInput" type="text" maxlength="14" /> 20 | </div> 21 | </li> 22 | </ul> 23 | 24 | <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> 25 | <script src="/socket.io/socket.io.js"></script> 26 | <script src="/main.js"></script> 27 | </body> 28 | </html> -------------------------------------------------------------------------------- /examples/cluster-nginx/client/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install --prod 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 3000 15 | CMD [ "npm", "start" ] 16 | -------------------------------------------------------------------------------- /examples/cluster-nginx/client/index.js: -------------------------------------------------------------------------------- 1 | const socket = require('socket.io-client')('ws://nginx'); 2 | 3 | socket.on('connect', () => { 4 | console.log('connected'); 5 | }); 6 | 7 | socket.on('my-name-is', (serverName) => { 8 | console.log(`connected to ${serverName}`); 9 | }); 10 | 11 | socket.on('disconnect', (reason) => { 12 | console.log(`disconnected due to ${reason}`); 13 | }); 14 | -------------------------------------------------------------------------------- /examples/cluster-nginx/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-chat", 3 | "version": "0.0.0", 4 | "description": "A simple chat client using socket.io", 5 | "main": "index.js", 6 | "author": "Grant Timmerman", 7 | "private": true, 8 | "license": "MIT", 9 | "dependencies": { 10 | "socket.io-client": "^4.0.0" 11 | }, 12 | "scripts": { 13 | "start": "node index.js" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/cluster-nginx/server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install --prod 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 3000 15 | CMD [ "npm", "start" ] 16 | -------------------------------------------------------------------------------- /examples/cluster-nginx/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-chat", 3 | "version": "0.0.0", 4 | "description": "A simple chat client using socket.io", 5 | "main": "index.js", 6 | "author": "Grant Timmerman", 7 | "private": true, 8 | "license": "MIT", 9 | "dependencies": { 10 | "@socket.io/redis-adapter": "^7.0.1", 11 | "express": "4.13.4", 12 | "redis": "^3.1.2", 13 | "socket.io": "^4.0.0" 14 | }, 15 | "scripts": { 16 | "start": "node index.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/cluster-nginx/server/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO Chat Example</title> 6 | <link rel="stylesheet" href="style.css"> 7 | </head> 8 | <body> 9 | <ul class="pages"> 10 | <li class="chat page"> 11 | <div class="chatArea"> 12 | <ul class="messages"></ul> 13 | </div> 14 | <input class="inputMessage" placeholder="Type here..."/> 15 | </li> 16 | <li class="login page"> 17 | <div class="form"> 18 | <h3 class="title">What's your nickname?</h3> 19 | <input class="usernameInput" type="text" maxlength="14" /> 20 | </div> 21 | </li> 22 | </ul> 23 | 24 | <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> 25 | <script src="/socket.io/socket.io.js"></script> 26 | <script src="/main.js"></script> 27 | </body> 28 | </html> -------------------------------------------------------------------------------- /examples/cluster-traefik/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Socket.IO Chat with traefik & [redis](https://redis.io/) 3 | 4 | A simple chat demo for Socket.IO 5 | 6 | ## How to use 7 | 8 | Install [Docker Compose](https://docs.docker.com/compose/install/), then: 9 | 10 | ``` 11 | $ docker-compose up -d 12 | ``` 13 | 14 | And then point your browser to `http://localhost:3000`. 15 | 16 | You can then scale the server to multiple instances: 17 | 18 | ``` 19 | $ docker-compose up -d --scale=server=7 20 | ``` 21 | 22 | The session stickiness, which is [required](https://socket.io/docs/v3/using-multiple-nodes/) when using multiple Socket.IO server instances, is achieved with a cookie. More information [here](https://doc.traefik.io/traefik/v2.0/routing/services/#sticky-sessions). 23 | -------------------------------------------------------------------------------- /examples/cluster-traefik/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | traefik: 5 | image: traefik:2.4 6 | volumes: 7 | - ./traefik.yml:/etc/traefik/traefik.yml 8 | - /var/run/docker.sock:/var/run/docker.sock 9 | links: 10 | - server 11 | ports: 12 | - "3000:80" 13 | - "8080:8080" 14 | 15 | server: 16 | build: ./server 17 | links: 18 | - redis 19 | labels: 20 | - "traefik.http.routers.chat.rule=PathPrefix(`/`)" 21 | - traefik.http.services.chat.loadBalancer.sticky.cookie.name=server_id 22 | - traefik.http.services.chat.loadBalancer.sticky.cookie.httpOnly=true 23 | 24 | redis: 25 | image: redis:6-alpine 26 | labels: 27 | - traefik.enable=false 28 | -------------------------------------------------------------------------------- /examples/cluster-traefik/server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install --prod 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 3000 15 | CMD [ "npm", "start" ] 16 | -------------------------------------------------------------------------------- /examples/cluster-traefik/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-chat", 3 | "version": "0.0.0", 4 | "description": "A simple chat client using socket.io", 5 | "main": "index.js", 6 | "author": "Grant Timmerman", 7 | "private": true, 8 | "license": "MIT", 9 | "dependencies": { 10 | "express": "4.13.4", 11 | "socket.io": "^4.0.0", 12 | "socket.io-redis": "^6.0.1" 13 | }, 14 | "scripts": { 15 | "start": "node index.js" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/cluster-traefik/server/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO Chat Example</title> 6 | <link rel="stylesheet" href="style.css"> 7 | </head> 8 | <body> 9 | <ul class="pages"> 10 | <li class="chat page"> 11 | <div class="chatArea"> 12 | <ul class="messages"></ul> 13 | </div> 14 | <input class="inputMessage" placeholder="Type here..."/> 15 | </li> 16 | <li class="login page"> 17 | <div class="form"> 18 | <h3 class="title">What's your nickname?</h3> 19 | <input class="usernameInput" type="text" maxlength="14" /> 20 | </div> 21 | </li> 22 | </ul> 23 | 24 | <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> 25 | <script src="/socket.io/socket.io.js"></script> 26 | <script src="/main.js"></script> 27 | </body> 28 | </html> -------------------------------------------------------------------------------- /examples/cluster-traefik/traefik.yml: -------------------------------------------------------------------------------- 1 | 2 | api: 3 | insecure: true 4 | 5 | entryPoints: 6 | web: 7 | address: ":80" 8 | 9 | providers: 10 | docker: {} 11 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/README.md: -------------------------------------------------------------------------------- 1 | # Example with connection state recovery 2 | 3 | This example shows how to use the [Connection state recovery feature](https://socket.io/docs/v4/connection-state-recovery). 4 | 5 |  6 | 7 | ## How to use 8 | 9 | ```shell 10 | # choose your module syntax (either ES modules or CommonJS) 11 | $ cd esm/ 12 | 13 | # install the dependencies 14 | $ npm i 15 | 16 | # start the server 17 | $ node index.js 18 | ``` 19 | 20 | And point your browser to `http://localhost:3000`. 21 | 22 | You can also run this example directly in your browser on: 23 | 24 | - [CodeSandbox](https://codesandbox.io/p/sandbox/github/socketio/socket.io/tree/main/examples/connection-state-recovery-example/esm?file=index.js) 25 | - [StackBlitz](https://stackblitz.com/github/socketio/socket.io/tree/main/examples/connection-state-recovery-example/esm?file=index.js) 26 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/assets/csr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/connection-state-recovery-example/assets/csr.gif -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/cjs/.codesandbox/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20-bullseye 2 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/cjs/.codesandbox/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // These tasks will run in order when initializing your CodeSandbox project. 3 | "setupTasks": [ 4 | { 5 | "name": "Install Dependencies", 6 | "command": "npm install" 7 | } 8 | ], 9 | 10 | // These tasks can be run from CodeSandbox. Running one will open a log in the app. 11 | "tasks": { 12 | "npm start": { 13 | "name": "npm start", 14 | "command": "npm start", 15 | "runAtStart": true 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connection-state-recovery-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "commonjs", 6 | "description": "Example with connection state recovery", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "socket.io": "^4.7.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/esm/.codesandbox/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20-bullseye 2 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/esm/.codesandbox/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // These tasks will run in order when initializing your CodeSandbox project. 3 | "setupTasks": [ 4 | { 5 | "name": "Install Dependencies", 6 | "command": "npm install" 7 | } 8 | ], 9 | 10 | // These tasks can be run from CodeSandbox. Running one will open a log in the app. 11 | "tasks": { 12 | "npm start": { 13 | "name": "npm start", 14 | "command": "npm start", 15 | "runAtStart": true 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/connection-state-recovery-example/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connection-state-recovery-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with connection state recovery", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "socket.io": "^4.7.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/create-react-app-example/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /examples/create-react-app-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/create-react-app-example/public/favicon.ico -------------------------------------------------------------------------------- /examples/create-react-app-example/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/create-react-app-example/public/logo192.png -------------------------------------------------------------------------------- /examples/create-react-app-example/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/create-react-app-example/public/logo512.png -------------------------------------------------------------------------------- /examples/create-react-app-example/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/create-react-app-example/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/create-react-app-example/server.js: -------------------------------------------------------------------------------- 1 | const io = require('socket.io')({ 2 | cors: { 3 | origin: ['http://localhost:3000'] 4 | } 5 | }); 6 | 7 | io.on('connection', socket => { 8 | console.log(`connect: ${socket.id}`); 9 | 10 | socket.on('hello!', () => { 11 | console.log(`hello from ${socket.id}`); 12 | }); 13 | 14 | socket.on('disconnect', () => { 15 | console.log(`disconnect: ${socket.id}`); 16 | }); 17 | }); 18 | 19 | io.listen(3001); 20 | 21 | setInterval(() => { 22 | io.emit('message', new Date().toISOString()); 23 | }, 1000); 24 | -------------------------------------------------------------------------------- /examples/create-react-app-example/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/create-react-app-example/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(<App />); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /examples/create-react-app-example/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /examples/create-react-app-example/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | const container = document.getElementById('root'); 8 | const root = createRoot(container) 9 | root.render( 10 | <React.StrictMode> 11 | <App /> 12 | </React.StrictMode> 13 | ); 14 | 15 | // If you want your app to work offline and load faster, you can change 16 | // unregister() to register() below. Note this comes with some pitfalls. 17 | // Learn more about service workers: https://bit.ly/CRA-PWA 18 | serviceWorker.unregister(); 19 | -------------------------------------------------------------------------------- /examples/create-react-app-example/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /examples/custom-parsers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parsers", 3 | "version": "1.0.0", 4 | "description": "Various socket.io parsers", 5 | "scripts": { 6 | "build": "webpack --config ./support/webpack.config.js", 7 | "start": "npm run build && node ./src/server.js" 8 | }, 9 | "author": "Damien Arrachequesne", 10 | "license": "MIT", 11 | "dependencies": { 12 | "component-emitter": "^1.2.1", 13 | "express": "^4.15.2", 14 | "schemapack": "^1.4.2", 15 | "socket.io": "^4.0.0", 16 | "socket.io-client": "^4.0.0", 17 | "socket.io-json-parser": "^3.0.0", 18 | "socket.io-msgpack-parser": "^3.0.1", 19 | "webpack": "^2.4.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/custom-parsers/public/.gitignore: -------------------------------------------------------------------------------- 1 | *.bundle.js 2 | -------------------------------------------------------------------------------- /examples/custom-parsers/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO custom parsers</title> 6 | </head> 7 | <body> 8 | <script src="client1.bundle.js"></script> 9 | <script src="client2.bundle.js"></script> 10 | <script src="client3.bundle.js"></script> 11 | <script src="client4.bundle.js"></script> 12 | </body> 13 | </html> 14 | -------------------------------------------------------------------------------- /examples/custom-parsers/src/client1.js: -------------------------------------------------------------------------------- 1 | 2 | const socket = require('socket.io-client')('localhost:3001', {}); 3 | 4 | socket.io.engine.on('data', (data) => console.log('[default]' + ' size= ' + (typeof data === 'string' ? data.length : data.byteLength))); 5 | 6 | socket.on('string', (data) => console.log('[default] [string]', data)); 7 | socket.on('numeric', (data) => console.log('[default] [numeric]', data)); 8 | socket.on('binary', (data) => console.log('[default] [binary]', data)); 9 | -------------------------------------------------------------------------------- /examples/custom-parsers/src/client2.js: -------------------------------------------------------------------------------- 1 | 2 | const customParser = require('socket.io-msgpack-parser'); 3 | const socket = require('socket.io-client')('http://localhost:3002', { 4 | parser: customParser 5 | }); 6 | 7 | socket.io.engine.on('data', (data) => console.log('[msgpack]' + ' size= ' + (typeof data === 'string' ? data.length : data.byteLength))); 8 | 9 | socket.on('string', (data) => console.log('[msgpack] [string]', data)); 10 | socket.on('numeric', (data) => console.log('[msgpack] [numeric]', data)); 11 | socket.on('binary', (data) => console.log('[msgpack] [binary]', data)); 12 | -------------------------------------------------------------------------------- /examples/custom-parsers/src/client3.js: -------------------------------------------------------------------------------- 1 | 2 | const customParser = require('socket.io-json-parser'); 3 | const socket = require('socket.io-client')('localhost:3003', { 4 | parser: customParser 5 | }); 6 | 7 | socket.io.engine.on('data', (data) => console.log('[json]' + ' size= ' + (typeof data === 'string' ? data.length : data.byteLength))); 8 | 9 | socket.on('string', (data) => console.log('[json] [string]', data)); 10 | socket.on('numeric', (data) => console.log('[json] [numeric]', data)); 11 | socket.on('binary', (data) => console.log('[json] [binary]', data)); 12 | -------------------------------------------------------------------------------- /examples/custom-parsers/src/client4.js: -------------------------------------------------------------------------------- 1 | 2 | const customParser = require('./custom-parser'); 3 | const socket = require('socket.io-client')('localhost:3004', { 4 | parser: customParser 5 | }); 6 | 7 | socket.io.engine.on('data', (data) => console.log('[custom]' + ' size= ' + (typeof data === 'string' ? data.length : data.byteLength))); 8 | 9 | socket.on('string', (data) => console.log('[custom] [string]', data)); 10 | socket.on('numeric', (data) => console.log('[custom] [numeric]', data)); 11 | socket.on('binary', (data) => console.log('[custom] [binary]', data)); 12 | -------------------------------------------------------------------------------- /examples/custom-parsers/support/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | entry: { 6 | client1: './src/client1.js', 7 | client2: './src/client2.js', 8 | client3: './src/client3.js', 9 | client4: './src/client4.js' 10 | }, 11 | output: { 12 | path: path.resolve(__dirname, '../public'), 13 | filename: '[name].bundle.js' 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /examples/es-modules/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Example with [ES modules](https://nodejs.org/api/esm.html) 3 | 4 | ## How to use 5 | 6 | ``` 7 | # install the dependencies 8 | $ npm ci 9 | 10 | # start the server 11 | $ node server.js 12 | 13 | # start the client 14 | $ node client.js 15 | ``` 16 | 17 | You need Node.js `>=12.17.0`. 18 | -------------------------------------------------------------------------------- /examples/es-modules/client.js: -------------------------------------------------------------------------------- 1 | import { Manager } from "socket.io-client"; 2 | 3 | const manager = new Manager("ws://localhost:8080"); 4 | const socket = manager.socket("/"); 5 | 6 | socket.on("connect", () => { 7 | console.log(`connect ${socket.id}`); 8 | }); 9 | 10 | socket.on("disconnect", () => { 11 | console.log(`disconnect`); 12 | }); 13 | 14 | setInterval(() => { 15 | socket.emit("ping", () => { 16 | console.log("pong"); 17 | }); 18 | }, 1000); 19 | -------------------------------------------------------------------------------- /examples/es-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es-modules", 3 | "version": "1.0.0", 4 | "description": "An example with ES modules (https://nodejs.org/api/esm.html)", 5 | "type": "module", 6 | "author": "Damien Arrachequesne", 7 | "license": "MIT", 8 | "engines": { 9 | "node": ">=12.17.0" 10 | }, 11 | "dependencies": { 12 | "socket.io": "^4.0.0", 13 | "socket.io-client": "^4.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/es-modules/server.js: -------------------------------------------------------------------------------- 1 | import { Server } from "socket.io"; 2 | 3 | const io = new Server(8080); 4 | 5 | io.on("connection", (socket) => { 6 | console.log(`connect ${socket.id}`); 7 | 8 | socket.on("ping", (cb) => { 9 | console.log("ping"); 10 | cb(); 11 | }); 12 | 13 | socket.on("disconnect", () => { 14 | console.log(`disconnect ${socket.id}`); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /examples/expo-example/.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | 11 | # Native 12 | *.orig.* 13 | *.jks 14 | *.p8 15 | *.p12 16 | *.key 17 | *.mobileprovision 18 | 19 | # Metro 20 | .metro-health-check* 21 | 22 | # debug 23 | npm-debug.* 24 | yarn-debug.* 25 | yarn-error.* 26 | 27 | # macOS 28 | .DS_Store 29 | *.pem 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /examples/expo-example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "expo-example", 4 | "slug": "expo-example", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "assetBundlePatterns": [ 15 | "**/*" 16 | ], 17 | "ios": { 18 | "supportsTablet": true 19 | }, 20 | "android": { 21 | "adaptiveIcon": { 22 | "foregroundImage": "./assets/adaptive-icon.png", 23 | "backgroundColor": "#ffffff" 24 | } 25 | }, 26 | "web": { 27 | "favicon": "./assets/favicon.png" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/expo-example/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/expo-example/assets/adaptive-icon.png -------------------------------------------------------------------------------- /examples/expo-example/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/expo-example/assets/favicon.png -------------------------------------------------------------------------------- /examples/expo-example/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/expo-example/assets/icon.png -------------------------------------------------------------------------------- /examples/expo-example/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/expo-example/assets/splash.png -------------------------------------------------------------------------------- /examples/expo-example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /examples/expo-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-example", 3 | "version": "1.0.0", 4 | "main": "node_modules/expo/AppEntry.js", 5 | "scripts": { 6 | "start": "expo start", 7 | "android": "expo start --android", 8 | "ios": "expo start --ios", 9 | "web": "expo start --web" 10 | }, 11 | "dependencies": { 12 | "@expo/metro-runtime": "~3.1.3", 13 | "expo": "~50.0.14", 14 | "expo-status-bar": "~1.11.1", 15 | "react": "18.2.0", 16 | "react-dom": "18.2.0", 17 | "react-native": "0.73.6", 18 | "react-native-web": "~0.19.6", 19 | "socket.io-client": "^4.7.5" 20 | }, 21 | "devDependencies": { 22 | "@babel/core": "^7.20.0" 23 | }, 24 | "private": true 25 | } 26 | -------------------------------------------------------------------------------- /examples/expo-example/server/index.js: -------------------------------------------------------------------------------- 1 | import { Server } from 'socket.io'; 2 | 3 | const io = new Server({ 4 | cors: { 5 | origin: ['http://localhost:8081'] 6 | } 7 | }); 8 | 9 | io.on('connection', (socket) => { 10 | console.log(`connect: ${socket.id}`, socket.request.headers); 11 | 12 | socket.on('disconnect', () => { 13 | console.log(`disconnect: ${socket.id}`); 14 | }); 15 | }); 16 | 17 | io.listen(3000); 18 | -------------------------------------------------------------------------------- /examples/expo-example/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "socket.io": "^4.7.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/expo-example/socket.js: -------------------------------------------------------------------------------- 1 | import { io } from 'socket.io-client'; 2 | 3 | export const socket = io('http://192.168.0.10:3000'); // use the IP address of your machine 4 | -------------------------------------------------------------------------------- /examples/express-session-example/README.md: -------------------------------------------------------------------------------- 1 | # Example with [express-session](https://www.npmjs.com/package/express-session) 2 | 3 | This example shows how to share a session context between [Express](http://expressjs.com/) and [Socket.IO](https://socket.io/docs/v4/): 4 | 5 |  6 | 7 | Please read the related guide: https://socket.io/how-to/use-with-express-session 8 | 9 | ## How to use 10 | 11 | ``` 12 | $ npm install 13 | $ npm start 14 | ``` 15 | 16 | And point your browser to `http://localhost:3000`. Optionally, specify a port by supplying the `PORT` env variable. 17 | -------------------------------------------------------------------------------- /examples/express-session-example/assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/express-session-example/assets/demo.gif -------------------------------------------------------------------------------- /examples/express-session-example/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-session-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "commonjs", 6 | "description": "Example with express-session (https://github.com/expressjs/session)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "express": "~4.17.3", 12 | "express-session": "~1.17.2", 13 | "socket.io": "^4.7.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/express-session-example/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-session-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with express-session (https://github.com/expressjs/session)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "express": "~4.17.3", 12 | "express-session": "~1.17.2", 13 | "socket.io": "^4.7.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/express-session-example/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-session-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with express-session (https://github.com/expressjs/session)", 7 | "scripts": { 8 | "start": "ts-node index.ts" 9 | }, 10 | "dependencies": { 11 | "@types/express": "^4.17.17", 12 | "@types/express-session": "^1.17.7", 13 | "@types/node": "^20.6.0", 14 | "express": "~4.17.3", 15 | "express-session": "~1.17.2", 16 | "socket.io": "^4.7.2", 17 | "ts-node": "^10.9.1", 18 | "typescript": "^5.2.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/express-session-example/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "moduleResolution": "NodeNext", 5 | "target": "ES2022", 6 | "strict": true 7 | }, 8 | "ts-node": { 9 | "esm": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/nestjs-example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir: __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /examples/nestjs-example/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | /build 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | pnpm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | lerna-debug.log* 14 | 15 | # OS 16 | .DS_Store 17 | 18 | # Tests 19 | /coverage 20 | /.nyc_output 21 | 22 | # IDEs and editors 23 | /.idea 24 | .project 25 | .classpath 26 | .c9/ 27 | *.launch 28 | .settings/ 29 | *.sublime-workspace 30 | 31 | # IDE - VSCode 32 | .vscode/* 33 | !.vscode/settings.json 34 | !.vscode/tasks.json 35 | !.vscode/launch.json 36 | !.vscode/extensions.json 37 | 38 | # dotenv environment variable files 39 | .env 40 | .env.development.local 41 | .env.test.local 42 | .env.production.local 43 | .env.local 44 | 45 | # temp directory 46 | .temp 47 | .tmp 48 | 49 | # Runtime data 50 | pids 51 | *.pid 52 | *.seed 53 | *.pid.lock 54 | 55 | # Diagnostic reports (https://nodejs.org/api/report.html) 56 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 57 | -------------------------------------------------------------------------------- /examples/nestjs-example/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /examples/nestjs-example/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get<AppController>(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Render } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get() 9 | @Render('index') 10 | root() { 11 | return { message: 'Hello world2!' }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | import { EventsModule } from './events/events.module'; 5 | 6 | @Module({ 7 | imports: [EventsModule], 8 | controllers: [AppController], 9 | providers: [AppService], 10 | }) 11 | export class AppModule {} 12 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello World!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/events/events.gateway.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MessageBody, 3 | SubscribeMessage, 4 | WebSocketGateway, 5 | WebSocketServer, 6 | } from '@nestjs/websockets'; 7 | import { Server } from 'socket.io'; 8 | 9 | @WebSocketGateway({}) 10 | export class EventsGateway { 11 | @WebSocketServer() 12 | io: Server; 13 | 14 | @SubscribeMessage('hello') 15 | handleEvent(@MessageBody() data: string): string { 16 | return data.split('').reverse().join(''); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/events/events.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { EventsGateway } from './events.gateway'; 3 | 4 | @Module({ 5 | providers: [EventsGateway], 6 | }) 7 | export class EventsModule {} 8 | -------------------------------------------------------------------------------- /examples/nestjs-example/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | import { NestExpressApplication } from '@nestjs/platform-express'; 4 | import { join } from 'node:path'; 5 | 6 | async function bootstrap() { 7 | const app = await NestFactory.create<NestExpressApplication>(AppModule); 8 | 9 | app.setBaseViewsDir(join(__dirname, '..', 'views')); 10 | app.setViewEngine('hbs'); 11 | 12 | await app.listen(3000); 13 | } 14 | 15 | bootstrap(); 16 | -------------------------------------------------------------------------------- /examples/nestjs-example/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /examples/nestjs-example/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.tsquot;, 6 | "transform": { 7 | "^.+\\.(t|j)squot;: "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/nestjs-example/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/nestjs-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "ES2021", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-app-router", 3 | "version": "0.1.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "next": "14.1.4", 14 | "react": "^18", 15 | "react-dom": "^18", 16 | "socket.io": "^4.7.5", 17 | "socket.io-client": "^4.7.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/public/vercel.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg> -------------------------------------------------------------------------------- /examples/nextjs-app-router/server.js: -------------------------------------------------------------------------------- 1 | import { createServer } from "http"; 2 | import next from "next"; 3 | import { Server } from "socket.io"; 4 | 5 | const dev = process.env.NODE_ENV !== "production"; 6 | const hostname = "localhost"; 7 | const port = 3000; 8 | // when using middleware `hostname` and `port` must be provided below 9 | const app = next({ dev, hostname, port }); 10 | const handler = app.getRequestHandler(); 11 | 12 | app.prepare().then(() => { 13 | const httpServer = createServer(handler); 14 | 15 | const io = new Server(httpServer); 16 | 17 | io.on("connection", (socket) => { 18 | // ... 19 | }); 20 | 21 | httpServer 22 | .once("error", (err) => { 23 | console.error(err); 24 | process.exit(1); 25 | }) 26 | .listen(port, () => { 27 | console.log(`> Ready on http://${hostname}:${port}`); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/nextjs-app-router/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/nextjs-app-router/src/app/layout.js: -------------------------------------------------------------------------------- 1 | import { Inter } from "next/font/google"; 2 | import "./globals.css"; 3 | 4 | const inter = Inter({ subsets: ["latin"] }); 5 | 6 | export const metadata = { 7 | title: "Create Next App", 8 | description: "Generated by create next app", 9 | }; 10 | 11 | export default function RootLayout({ children }) { 12 | return ( 13 | <html lang="en"> 14 | <body className={inter.className}>{children}</body> 15 | </html> 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /examples/nextjs-app-router/src/socket.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { io } from "socket.io-client"; 4 | 5 | export const socket = io(); 6 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | /src/.next/ 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | 29 | # local env files 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | }; 5 | 6 | export default nextConfig; 7 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-pages-router", 3 | "version": "0.1.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "node server.js", 8 | "build": "next build", 9 | "start": "NODE_ENV=production node server.js", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "next": "14.1.4", 14 | "react": "^18", 15 | "react-dom": "^18", 16 | "socket.io": "^4.7.5", 17 | "socket.io-client": "^4.7.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/nextjs-pages-router/public/favicon.ico -------------------------------------------------------------------------------- /examples/nextjs-pages-router/public/vercel.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg> -------------------------------------------------------------------------------- /examples/nextjs-pages-router/server.js: -------------------------------------------------------------------------------- 1 | import { createServer } from "http"; 2 | import next from "next"; 3 | import { Server } from "socket.io"; 4 | 5 | const dev = process.env.NODE_ENV !== "production"; 6 | const hostname = "localhost"; 7 | const port = 3000; 8 | // when using middleware `hostname` and `port` must be provided below 9 | const app = next({ dev, hostname, port }); 10 | const handler = app.getRequestHandler(); 11 | 12 | app.prepare().then(() => { 13 | const httpServer = createServer(handler); 14 | 15 | const io = new Server(httpServer); 16 | 17 | io.on("connection", (socket) => { 18 | // ... 19 | }); 20 | 21 | httpServer 22 | .once("error", (err) => { 23 | console.error(err); 24 | process.exit(1); 25 | }) 26 | .listen(port, () => { 27 | console.log(`> Ready on http://${hostname}:${port}`); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/src/pages/_app.js: -------------------------------------------------------------------------------- 1 | // import "@/styles/globals.css"; 2 | 3 | export default function App({ Component, pageProps }) { 4 | return <Component {...pageProps} />; 5 | } 6 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/src/pages/_document.js: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | 3 | export default function Document() { 4 | return ( 5 | <Html lang="en"> 6 | <Head /> 7 | <body> 8 | <Main /> 9 | <NextScript /> 10 | </body> 11 | </Html> 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/src/pages/api/hello.js: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | 3 | export default function handler(req, res) { 4 | res.status(200).json({ name: "John Doe" }); 5 | } 6 | -------------------------------------------------------------------------------- /examples/nextjs-pages-router/src/socket.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const isBrowser = typeof window !== "undefined"; 4 | 5 | // only create the Socket.IO client on the client side (no ssr) 6 | export const socket = isBrowser ? io() : {}; 7 | -------------------------------------------------------------------------------- /examples/nuxt-example/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | -------------------------------------------------------------------------------- /examples/nuxt-example/app.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div> 3 | <Connection /> 4 | </div> 5 | </template> 6 | -------------------------------------------------------------------------------- /examples/nuxt-example/components/socket.ts: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | export const socket = io(); 4 | -------------------------------------------------------------------------------- /examples/nuxt-example/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | 3 | export default defineNuxtConfig({ 4 | devtools: { 5 | enabled: true 6 | }, 7 | nitro: { 8 | experimental: { 9 | websocket: true 10 | }, 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /examples/nuxt-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "nuxt": "^3.11.1", 14 | "socket.io": "^4.7.5", 15 | "socket.io-client": "^4.7.5", 16 | "vue": "^3.4.21", 17 | "vue-router": "^4.3.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/nuxt-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/nuxt-example/public/favicon.ico -------------------------------------------------------------------------------- /examples/nuxt-example/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /examples/nuxt-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /examples/nwjs-example/README.md: -------------------------------------------------------------------------------- 1 | # Socket.IO with [NW.js](https://nwjs.io/) 2 | 3 | Guide: https://socket.io/how-to/use-with-nwjs 4 | 5 | ## How to use 6 | 7 | ### Client 8 | 9 | ```bash 10 | # install the dependencies 11 | $ npm i 12 | 13 | # start the app 14 | $ nw . 15 | ``` 16 | 17 | ### Server 18 | 19 | ```bash 20 | $ cd server 21 | 22 | # install the dependencies 23 | $ npm i 24 | 25 | # start the server 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/nwjs-example/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <body> 4 | <p>Status: <span id="status"></span></p> 5 | <p>Transport: <span id="transport"></span></p> 6 | 7 | <script> 8 | const { registerListeners, emit } = require("./index"); 9 | 10 | const statusSpan = document.getElementById("status"); 11 | const transportSpan = document.getElementById("transport"); 12 | 13 | statusSpan.innerText = "Disconnected"; 14 | transportSpan.innerText = "N/A"; 15 | 16 | registerListeners({ statusSpan, transportSpan }); 17 | 18 | emit("hello", "world"); 19 | </script> 20 | </body> 21 | </html> 22 | -------------------------------------------------------------------------------- /examples/nwjs-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "main": "index.html", 4 | "dependencies": { 5 | "socket.io-client": "^4.7.5" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/nwjs-example/server/index.js: -------------------------------------------------------------------------------- 1 | import { Server } from 'socket.io'; 2 | 3 | const io = new Server(); 4 | 5 | io.on('connection', (socket) => { 6 | console.log(`connect: ${socket.id}`); 7 | 8 | socket.on("hello", (val) => { 9 | console.log(val); 10 | }); 11 | 12 | socket.on('disconnect', () => { 13 | console.log(`disconnect: ${socket.id}`); 14 | }); 15 | }); 16 | 17 | io.listen(3000); 18 | -------------------------------------------------------------------------------- /examples/nwjs-example/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "socket.io": "^4.7.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/passport-example/assets/passport_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/passport-example/assets/passport_example.gif -------------------------------------------------------------------------------- /examples/passport-example/cjs/login.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Passport example</title> 6 | </head> 7 | <body> 8 | <p>Not authenticated</p> 9 | <form action="/login" method="post"> 10 | <div> 11 | <label for="username">Username:</label> 12 | <input type="text" id="username" name="username" /> 13 | <br/> 14 | </div> 15 | <div> 16 | <label for="password">Password:</label> 17 | <input type="password" id="password" name="password" /> 18 | </div> 19 | <div> 20 | <input type="submit" value="Submit" /> 21 | </div> 22 | </form> 23 | </body> 24 | </html> 25 | -------------------------------------------------------------------------------- /examples/passport-example/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passport-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "commonjs", 6 | "description": "Example with passport (https://www.passportjs.org)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "express": "~4.17.3", 12 | "express-session": "~1.17.2", 13 | "passport": "^0.7.0", 14 | "passport-local": "^1.0.0", 15 | "socket.io": "^4.7.2" 16 | }, 17 | "devDependencies": { 18 | "prettier": "^3.1.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/passport-example/esm/login.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Passport example</title> 6 | </head> 7 | <body> 8 | <p>Not authenticated</p> 9 | <form action="/login" method="post"> 10 | <div> 11 | <label for="username">Username:</label> 12 | <input type="text" id="username" name="username" /> 13 | <br/> 14 | </div> 15 | <div> 16 | <label for="password">Password:</label> 17 | <input type="password" id="password" name="password" /> 18 | </div> 19 | <div> 20 | <input type="submit" value="Submit" /> 21 | </div> 22 | </form> 23 | </body> 24 | </html> 25 | -------------------------------------------------------------------------------- /examples/passport-example/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passport-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with passport (https://www.passportjs.org)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "express": "~4.17.3", 12 | "express-session": "~1.17.2", 13 | "passport": "^0.7.0", 14 | "passport-local": "^1.0.0", 15 | "socket.io": "^4.7.2" 16 | }, 17 | "devDependencies": { 18 | "prettier": "^3.1.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/passport-example/ts/login.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Passport example</title> 6 | </head> 7 | <body> 8 | <p>Not authenticated</p> 9 | <form action="/login" method="post"> 10 | <div> 11 | <label for="username">Username:</label> 12 | <input type="text" id="username" name="username" /> 13 | <br/> 14 | </div> 15 | <div> 16 | <label for="password">Password:</label> 17 | <input type="password" id="password" name="password" /> 18 | </div> 19 | <div> 20 | <input type="submit" value="Submit" /> 21 | </div> 22 | </form> 23 | </body> 24 | </html> 25 | -------------------------------------------------------------------------------- /examples/passport-example/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passport-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with passport (https://www.passportjs.org)", 7 | "scripts": { 8 | "start": "ts-node index.ts" 9 | }, 10 | "dependencies": { 11 | "@types/express": "^4.17.17", 12 | "@types/express-session": "^1.17.7", 13 | "@types/node": "^20.6.0", 14 | "@types/passport": "^1.0.16", 15 | "express": "~4.17.3", 16 | "express-session": "~1.17.2", 17 | "passport": "^0.7.0", 18 | "passport-local": "^1.0.0", 19 | "socket.io": "^4.7.2", 20 | "ts-node": "^10.9.1", 21 | "typescript": "^5.2.2" 22 | }, 23 | "devDependencies": { 24 | "@types/passport-local": "^1.0.38", 25 | "prettier": "^3.1.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/passport-example/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "moduleResolution": "NodeNext", 5 | "target": "ES2022", 6 | "strict": true 7 | }, 8 | "ts-node": { 9 | "esm": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/passport-jwt-example/assets/passport_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/passport-jwt-example/assets/passport_example.gif -------------------------------------------------------------------------------- /examples/passport-jwt-example/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passport-jwt-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "commonjs", 6 | "description": "Example with passport and JWT (https://www.passportjs.org/packages/passport-jwt/)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "body-parser": "^1.20.2", 12 | "express": "~4.17.3", 13 | "jsonwebtoken": "^9.0.2", 14 | "passport": "^0.7.0", 15 | "passport-jwt": "^4.0.1", 16 | "socket.io": "^4.7.2" 17 | }, 18 | "devDependencies": { 19 | "prettier": "^3.1.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/passport-jwt-example/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passport-jwt-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with passport and JWT (https://www.passportjs.org/packages/passport-jwt/)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "body-parser": "^1.20.2", 12 | "express": "~4.17.3", 13 | "jsonwebtoken": "^9.0.2", 14 | "passport": "^0.7.0", 15 | "passport-jwt": "^4.0.1", 16 | "socket.io": "^4.7.2" 17 | }, 18 | "devDependencies": { 19 | "prettier": "^3.1.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/passport-jwt-example/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "passport-jwt-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "description": "Example with passport and JWT (https://www.passportjs.org/packages/passport-jwt/)", 7 | "scripts": { 8 | "start": "node index.js" 9 | }, 10 | "dependencies": { 11 | "@types/express": "^4.17.21", 12 | "@types/jsonwebtoken": "^9.0.5", 13 | "@types/passport": "^1.0.16", 14 | "@types/passport-jwt": "^4.0.0", 15 | "body-parser": "^1.20.2", 16 | "express": "~4.17.3", 17 | "jsonwebtoken": "^9.0.2", 18 | "passport": "^0.7.0", 19 | "passport-jwt": "^4.0.1", 20 | "socket.io": "^4.7.2", 21 | "ts-node": "^10.9.2", 22 | "typescript": "^5.3.3" 23 | }, 24 | "devDependencies": { 25 | "prettier": "^3.1.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/passport-jwt-example/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "moduleResolution": "NodeNext", 5 | "target": "ES2022", 6 | "strict": true 7 | }, 8 | "ts-node": { 9 | "esm": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/postgres-adapter-example/README.md: -------------------------------------------------------------------------------- 1 | # Example with `@socket.io/postgres-adapter` 2 | 3 | **Table of contents** 4 | 5 | <!-- TOC --> 6 | * [How to use](#how-to-use) 7 | * [Documentation](#documentation) 8 | <!-- TOC --> 9 | 10 | ## How to use 11 | 12 | ```bash 13 | # start the postgres server 14 | $ docker compose up -d 15 | 16 | # run the cluster 17 | $ node cluster.js 18 | 19 | # run the client 20 | $ node client.js 21 | ``` 22 | 23 | ## Documentation 24 | 25 | The documentation can be found here: https://socket.io/docs/v4/postgres-adapter/ 26 | -------------------------------------------------------------------------------- /examples/postgres-adapter-example/client.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const CLIENTS_COUNT = 3; 4 | const PORTS = [3000, 3001, 3002]; 5 | 6 | for (let i = 0; i < CLIENTS_COUNT; i++) { 7 | const socket = io(`ws://localhost:${PORTS[i % 3]}`, { 8 | // transports: ["polling"], 9 | // transports: ["websocket"], 10 | }); 11 | 12 | socket.on("connect", () => { 13 | console.log(`connected as ${socket.id}`); 14 | }); 15 | 16 | socket.on("connect_error", () => { 17 | console.log(`connect_error`); 18 | }); 19 | 20 | socket.on("disconnect", (reason) => { 21 | console.log(`disconnected due to ${reason}`); 22 | }); 23 | 24 | socket.on("hello", (socketId, pid) => { 25 | console.log(`received "hello" from ${socketId} (process: ${pid})`); 26 | }); 27 | 28 | setInterval(() => { 29 | socket.emit("hello"); 30 | }, 2000); 31 | } 32 | -------------------------------------------------------------------------------- /examples/postgres-adapter-example/cluster.js: -------------------------------------------------------------------------------- 1 | import cluster from 'node:cluster'; 2 | 3 | const SERVERS_COUNT = 3; 4 | 5 | cluster.setupPrimary({ 6 | exec: 'server.js', 7 | }); 8 | 9 | for (let i = 0; i < SERVERS_COUNT; i++) { 10 | cluster.fork({ 11 | PORT: 3000 + i 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /examples/postgres-adapter-example/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | postgres: 3 | image: postgres:14 4 | ports: 5 | - "5432:5432" 6 | environment: 7 | POSTGRES_PASSWORD: "changeit" 8 | -------------------------------------------------------------------------------- /examples/postgres-adapter-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "postgres-adapter-example", 4 | "version": "0.0.1", 5 | "type": "module", 6 | "dependencies": { 7 | "@socket.io/postgres-adapter": "^0.4.0", 8 | "pg": "^8.12.0", 9 | "socket.io": "^4.7.5", 10 | "socket.io-client": "^4.7.5" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/private-messaging/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | package-lock.json 25 | -------------------------------------------------------------------------------- /examples/private-messaging/README.md: -------------------------------------------------------------------------------- 1 | # Private messaging with Socket.IO 2 | 3 | Please read the related guide: 4 | 5 | - [Part I](https://socket.io/get-started/private-messaging-part-1/): initial implementation 6 | - [Part II](https://socket.io/get-started/private-messaging-part-2/): persistent user ID 7 | - [Part III](https://socket.io/get-started/private-messaging-part-3/): persistent messages 8 | - [Part IV](https://socket.io/get-started/private-messaging-part-4/): scaling up 9 | 10 | ## Running the frontend 11 | 12 | ``` 13 | npm install 14 | npm run serve 15 | ``` 16 | 17 | ### Running the server 18 | 19 | ``` 20 | cd server 21 | npm install 22 | npm start 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/private-messaging/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /examples/private-messaging/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/private-messaging/public/favicon.ico -------------------------------------------------------------------------------- /examples/private-messaging/public/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/examples/private-messaging/public/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /examples/private-messaging/public/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang=""> 3 | <head> 4 | <meta charset="utf-8"> 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 | <meta name="viewport" content="width=device-width,initial-scale=1.0"> 7 | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> 8 | <title>Private messaging with Socket.IO</title> 9 | </head> 10 | <body> 11 | <noscript> 12 | <strong>We're sorry but this application doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> 13 | </noscript> 14 | <div id="app"></div> 15 | <!-- built files will be auto injected --> 16 | </body> 17 | </html> 18 | -------------------------------------------------------------------------------- /examples/private-messaging/server/cluster.js: -------------------------------------------------------------------------------- 1 | const cluster = require("cluster"); 2 | const http = require("http"); 3 | const { setupMaster } = require("@socket.io/sticky"); 4 | 5 | const WORKERS_COUNT = 4; 6 | 7 | if (cluster.isMaster) { 8 | console.log(`Master ${process.pid} is running`); 9 | 10 | for (let i = 0; i < WORKERS_COUNT; i++) { 11 | cluster.fork(); 12 | } 13 | 14 | cluster.on("exit", (worker) => { 15 | console.log(`Worker ${worker.process.pid} died`); 16 | cluster.fork(); 17 | }); 18 | 19 | const httpServer = http.createServer(); 20 | setupMaster(httpServer, { 21 | loadBalancingMethod: "least-connection", // either "random", "round-robin" or "least-connection" 22 | }); 23 | const PORT = process.env.PORT || 3000; 24 | 25 | httpServer.listen(PORT, () => 26 | console.log(`server listening at http://localhost:${PORT}`) 27 | ); 28 | } else { 29 | console.log(`Worker ${process.pid} started`); 30 | require("./index"); 31 | } 32 | -------------------------------------------------------------------------------- /examples/private-messaging/server/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | redis: 5 | image: redis:5 6 | ports: 7 | - "6379:6379" 8 | -------------------------------------------------------------------------------- /examples/private-messaging/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node cluster.js" 8 | }, 9 | "author": "Damien Arrachequesne <damien.arrachequesne@gmail.com>", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@socket.io/sticky": "^1.0.0", 13 | "ioredis": "^4.22.0", 14 | "socket.io": "^4.0.0", 15 | "socket.io-redis": "^6.0.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/private-messaging/src/components/SelectUsername.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div class="select-username"> 3 | <form @submit.prevent="onSubmit"> 4 | <input v-model="username" placeholder="Your username..." /> 5 | <button :disabled="!isValid">Send</button> 6 | </form> 7 | </div> 8 | </template> 9 | 10 | <script> 11 | export default { 12 | name: "SelectUsername", 13 | data() { 14 | return { 15 | username: "", 16 | }; 17 | }, 18 | computed: { 19 | isValid() { 20 | return this.username.length > 2; 21 | }, 22 | }, 23 | methods: { 24 | onSubmit() { 25 | this.$emit("input", this.username); 26 | }, 27 | }, 28 | }; 29 | </script> 30 | 31 | <style scoped> 32 | .select-username { 33 | width: 300px; 34 | margin: 200px auto 0; 35 | } 36 | </style> 37 | -------------------------------------------------------------------------------- /examples/private-messaging/src/components/StatusIcon.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <i class="icon" :class="{ connected: connected }"></i> 3 | </template> 4 | 5 | <script> 6 | export default { 7 | name: "StatusIcon", 8 | props: { 9 | connected: Boolean, 10 | }, 11 | }; 12 | </script> 13 | 14 | <style scoped> 15 | .icon { 16 | height: 8px; 17 | width: 8px; 18 | border-radius: 50%; 19 | display: inline-block; 20 | background-color: #e38968; 21 | margin-right: 6px; 22 | } 23 | 24 | .icon.connected { 25 | background-color: #86bb71; 26 | } 27 | </style> 28 | -------------------------------------------------------------------------------- /examples/private-messaging/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | 4 | Vue.config.productionTip = false; 5 | 6 | new Vue({ 7 | render: (h) => h(App), 8 | }).$mount("#app"); 9 | -------------------------------------------------------------------------------- /examples/private-messaging/src/socket.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const URL = "http://localhost:3000"; 4 | const socket = io(URL, { autoConnect: false }); 5 | 6 | socket.onAny((event, ...args) => { 7 | console.log(event, args); 8 | }); 9 | 10 | export default socket; 11 | -------------------------------------------------------------------------------- /examples/rollup-server-bundle/.gitignore: -------------------------------------------------------------------------------- 1 | bundle.js 2 | -------------------------------------------------------------------------------- /examples/rollup-server-bundle/index.js: -------------------------------------------------------------------------------- 1 | import { Server } from "socket.io"; 2 | 3 | new Server(0); 4 | -------------------------------------------------------------------------------- /examples/rollup-server-bundle/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup-server-bundle", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "author": "Damien Arrachequesne <damien.arrachequesne@gmail.com>", 8 | "license": "ISC", 9 | "scripts": { 10 | "build": "rollup --config rollup.config.js" 11 | }, 12 | "devDependencies": { 13 | "@rollup/plugin-commonjs": "^21.0.3", 14 | "@rollup/plugin-json": "^4.1.0", 15 | "@rollup/plugin-node-resolve": "^13.1.3", 16 | "rollup": "^2.70.1", 17 | "socket.io": "^4.4.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/rollup-server-bundle/rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from "@rollup/plugin-node-resolve"; 2 | import commonjs from "@rollup/plugin-commonjs"; 3 | import json from "@rollup/plugin-json"; 4 | 5 | export default { 6 | input: "index.js", 7 | output: { 8 | file: "bundle.js", 9 | format: "esm", 10 | }, 11 | plugins: [resolve(), commonjs(), json({ compact: true })], 12 | }; 13 | -------------------------------------------------------------------------------- /examples/tweet-stream/index.js: -------------------------------------------------------------------------------- 1 | 2 | const Twitter = require('node-tweet-stream'); 3 | const twitter = new Twitter({ 4 | consumer_key: process.env.TWITTER_CONSUMER_KEY, 5 | consumer_secret: process.env.TWITTER_CONSUMER_SECRET, 6 | token: process.env.TWITTER_TOKEN, 7 | token_secret: process.env.TWITTER_TOKEN_SECRET 8 | }); 9 | 10 | const io = require('socket.io')(process.env.PORT || 3000, { 11 | cors: { 12 | origin: true 13 | } 14 | }); 15 | 16 | twitter.track('socket.io'); 17 | twitter.track('javascript'); 18 | 19 | let tweets = []; 20 | const MAX_TWEETS = 10; 21 | 22 | io.on('connect', socket => { 23 | socket.emit('buffer', tweets); 24 | }); 25 | 26 | twitter.on('tweet', tweet => { 27 | io.emit('tweet', tweet); 28 | tweets.unshift(tweet); 29 | tweets = tweets.slice(0, MAX_TWEETS); 30 | }); 31 | 32 | twitter.on('error', err => { 33 | console.error(err); 34 | }); 35 | -------------------------------------------------------------------------------- /examples/tweet-stream/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-tweet-stream", 3 | "version": "1.0.0", 4 | "description": "tweets about socket.io and javascript", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "keywords": [ 10 | "socket.io", 11 | "tweet", 12 | "stream" 13 | ], 14 | "author": "Damien Arrachequesne", 15 | "license": "MIT", 16 | "dependencies": { 17 | "node-tweet-stream": "^2.0.1", 18 | "socket.io": "^4.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/typescript-client-example/cjs/client.ts: -------------------------------------------------------------------------------- 1 | import { io, type Socket } from "socket.io-client"; 2 | 3 | interface ServerToClientEvents { 4 | hello: (val: string) => void; 5 | } 6 | 7 | interface ClientToServerEvents { 8 | ping: (cb: () => void) => void; 9 | } 10 | 11 | const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io("ws://localhost:8080/"); 12 | 13 | socket.on("connect", () => { 14 | console.log(`connect ${socket.id}`); 15 | }); 16 | 17 | socket.on("hello", (val) => { 18 | console.log(`got ${val}`); 19 | }); 20 | 21 | socket.on("disconnect", () => { 22 | console.log(`disconnect`); 23 | }); 24 | 25 | setInterval(() => { 26 | const start = Date.now(); 27 | socket.emit("ping", () => { 28 | console.log(`pong (latency: ${Date.now() - start} ms)`); 29 | }); 30 | }, 1000); 31 | -------------------------------------------------------------------------------- /examples/typescript-client-example/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-client-example-cjs", 3 | "version": "0.0.1", 4 | "description": "An example with TypeScript", 5 | "type": "commonjs", 6 | "private": true, 7 | "scripts": { 8 | "build": "tsc", 9 | "start": "ts-node client.ts" 10 | }, 11 | "license": "MIT", 12 | "dependencies": { 13 | "socket.io-client": "^4.8.0", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/typescript-client-example/cjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "es2022", 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "strict": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/typescript-client-example/esm/client.ts: -------------------------------------------------------------------------------- 1 | import { io, type Socket } from "socket.io-client"; 2 | 3 | interface ServerToClientEvents { 4 | hello: (val: string) => void; 5 | } 6 | 7 | interface ClientToServerEvents { 8 | ping: (cb: () => void) => void; 9 | } 10 | 11 | const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io("ws://localhost:8080/"); 12 | 13 | socket.on("connect", () => { 14 | console.log(`connect ${socket.id}`); 15 | }); 16 | 17 | socket.on("hello", (val) => { 18 | console.log(`got ${val}`); 19 | }); 20 | 21 | socket.on("disconnect", () => { 22 | console.log(`disconnect`); 23 | }); 24 | 25 | setInterval(() => { 26 | const start = Date.now(); 27 | socket.emit("ping", () => { 28 | console.log(`pong (latency: ${Date.now() - start} ms)`); 29 | }); 30 | }, 1000); 31 | -------------------------------------------------------------------------------- /examples/typescript-client-example/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-client-example-esm", 3 | "version": "0.0.1", 4 | "description": "An example with TypeScript", 5 | "type": "module", 6 | "private": true, 7 | "scripts": { 8 | "build": "tsc", 9 | "start": "node --no-warnings=ExperimentalWarning --loader ts-node/esm client.ts" 10 | }, 11 | "license": "MIT", 12 | "dependencies": { 13 | "socket.io-client": "^4.8.0", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/typescript-client-example/esm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "es2022", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/typescript-example/cjs/client.ts: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const socket = io("ws://localhost:8080/", {}); 4 | 5 | socket.on("connect", () => { 6 | console.log(`connect ${socket.id}`); 7 | }); 8 | 9 | socket.on("disconnect", () => { 10 | console.log(`disconnect`); 11 | }); 12 | 13 | setInterval(() => { 14 | const start = Date.now(); 15 | socket.emit("ping", () => { 16 | console.log(`pong (latency: ${Date.now() - start} ms)`); 17 | }); 18 | }, 1000); 19 | -------------------------------------------------------------------------------- /examples/typescript-example/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-example", 3 | "version": "1.0.0", 4 | "description": "An example with TypeScript", 5 | "type": "commonjs", 6 | "private": true, 7 | "scripts": { 8 | "build": "tsc", 9 | "start:server": "ts-node server.ts", 10 | "start:client": "ts-node client.ts" 11 | }, 12 | "author": "Damien Arrachequesne", 13 | "license": "MIT", 14 | "dependencies": { 15 | "socket.io": "^4.7.5", 16 | "socket.io-client": "^4.7.5", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.4.5" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/typescript-example/cjs/server.ts: -------------------------------------------------------------------------------- 1 | import { Server } from "socket.io"; 2 | 3 | const io = new Server(8080); 4 | 5 | io.on("connection", (socket) => { 6 | console.log(`connect ${socket.id}`); 7 | 8 | socket.on("ping", (cb) => { 9 | console.log("ping"); 10 | cb(); 11 | }); 12 | 13 | socket.on("disconnect", () => { 14 | console.log(`disconnect ${socket.id}`); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /examples/typescript-example/cjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "es2022", 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/typescript-example/esm/client.ts: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const socket = io("ws://localhost:8080/", {}); 4 | 5 | socket.on("connect", () => { 6 | console.log(`connect ${socket.id}`); 7 | }); 8 | 9 | socket.on("disconnect", () => { 10 | console.log(`disconnect`); 11 | }); 12 | 13 | setInterval(() => { 14 | const start = Date.now(); 15 | socket.emit("ping", () => { 16 | console.log(`pong (latency: ${Date.now() - start} ms)`); 17 | }); 18 | }, 1000); 19 | -------------------------------------------------------------------------------- /examples/typescript-example/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-example", 3 | "version": "1.0.0", 4 | "description": "An example with TypeScript", 5 | "type": "module", 6 | "private": true, 7 | "scripts": { 8 | "build": "tsc", 9 | "start:server": "node --no-warnings=ExperimentalWarning --loader ts-node/esm server.ts", 10 | "start:client": "node --no-warnings=ExperimentalWarning --loader ts-node/esm client.ts" 11 | }, 12 | "author": "Damien Arrachequesne", 13 | "license": "MIT", 14 | "dependencies": { 15 | "socket.io": "^4.7.5", 16 | "socket.io-client": "^4.7.5", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.4.5" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/typescript-example/esm/server.ts: -------------------------------------------------------------------------------- 1 | import { Server } from "socket.io"; 2 | 3 | const io = new Server(8080); 4 | 5 | io.on("connection", (socket) => { 6 | console.log(`connect ${socket.id}`); 7 | 8 | socket.on("ping", (cb) => { 9 | console.log("ping"); 10 | cb(); 11 | }); 12 | 13 | socket.on("disconnect", () => { 14 | console.log(`disconnect ${socket.id}`); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /examples/typescript-example/esm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "es2022", 5 | "module": "esnext", 6 | "moduleResolution": "node" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/webpack-build-server/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Socket.IO WebPack build 3 | 4 | A sample Webpack build for the server. 5 | 6 | ## How to use 7 | 8 | ``` 9 | $ npm i 10 | $ npm run build 11 | $ npm start 12 | ``` 13 | 14 | **Note:** 15 | 16 | - the `bufferutil` and `utf-8-validate` are optional dependencies from `ws`, compiled from native code, which are meant to improve performance ([ref](https://github.com/websockets/ws#opt-in-for-performance)). You can also omit them, as they have their JS fallback, and ignore the WebPack warning. 17 | 18 | - the server is initiated with `serveClient` set to `false`, so it will not serve the client file. 19 | -------------------------------------------------------------------------------- /examples/webpack-build-server/index.js: -------------------------------------------------------------------------------- 1 | const { Server } = require("socket.io"); 2 | 3 | const clientFile = require("./node_modules/socket.io/client-dist/socket.io.min?raw"); 4 | const clientMap = require("./node_modules/socket.io/client-dist/socket.io.min.js.map?raw"); 5 | 6 | Server.sendFile = (filename, req, res) => { 7 | res.end(filename.endsWith(".map") ? clientMap : clientFile); 8 | }; 9 | 10 | const io = new Server(); 11 | 12 | io.on("connection", socket => { 13 | console.log(`connect ${socket.id}`); 14 | 15 | socket.on("disconnect", (reason) => { 16 | console.log(`disconnect ${socket.id} due to ${reason}`); 17 | }); 18 | }); 19 | 20 | io.listen(3000); 21 | -------------------------------------------------------------------------------- /examples/webpack-build-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-build-server", 3 | "version": "1.0.0", 4 | "description": "A sample Webpack build (for the server)", 5 | "scripts": { 6 | "start": "node dist/server.js", 7 | "build": "webpack" 8 | }, 9 | "author": "Damien Arrachequesne", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "bufferutil": "^4.0.3", 13 | "socket.io": "^4.0.0", 14 | "utf-8-validate": "^5.0.5", 15 | "webpack": "^5.39.0", 16 | "webpack-cli": "^4.7.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/webpack-build-server/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | entry: "./index.js", 5 | target: "node", 6 | mode: "production", 7 | output: { 8 | path: path.resolve(__dirname, "dist"), 9 | filename: "index.js", 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | resourceQuery: /raw/, 15 | type: "asset/source", 16 | }, 17 | ], 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /examples/webpack-build/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Socket.IO WebPack build 3 | 4 | A sample Webpack build for the browser. 5 | 6 | ## How to use 7 | 8 | ``` 9 | $ npm i 10 | $ npm run build 11 | ``` 12 | -------------------------------------------------------------------------------- /examples/webpack-build/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO WebPack Example</title> 6 | </head> 7 | <body> 8 | 9 | <script src="dist/bundle.js"></script> 10 | 11 | </body> 12 | </html> 13 | -------------------------------------------------------------------------------- /examples/webpack-build/index.js: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | const socket = io("http://localhost:3000"); 4 | 5 | socket.on("connect", () => { 6 | console.log(`connect ${socket.id}`); 7 | }); 8 | 9 | socket.on("connect_error", (err) => { 10 | console.log(`connect_error due to ${err.message}`); 11 | }); 12 | 13 | socket.on("disconnect", (reason) => { 14 | console.log(`disconnect due to ${reason}`); 15 | }); 16 | -------------------------------------------------------------------------------- /examples/webpack-build/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-build", 3 | "version": "1.0.0", 4 | "description": "A sample Webpack build", 5 | "type": "module", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "author": "Damien Arrachequesne", 10 | "license": "MIT", 11 | "dependencies": { 12 | "socket.io-client": "^4.4.1", 13 | "webpack": "^5.72.0", 14 | "webpack-cli": "^4.9.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/webpack-build/webpack.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | entry: "./index.js", 3 | mode: "production", 4 | output: { 5 | filename: "bundle.js", 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /examples/webtransport/.gitignore: -------------------------------------------------------------------------------- 1 | *.pem 2 | -------------------------------------------------------------------------------- /examples/webtransport/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Socket.IO WebTransport example 3 | 4 | ## How to use 5 | 6 | ```shell 7 | # generate a self-signed certificate 8 | $ ./generate_cert.sh 9 | 10 | # install dependencies 11 | $ npm i 12 | 13 | # start the server 14 | $ node index.js 15 | 16 | # open a Chrome browser 17 | $ ./open_chrome.sh 18 | ``` 19 | -------------------------------------------------------------------------------- /examples/webtransport/generate_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | openssl req -new -x509 -nodes \ 3 | -out cert.pem \ 4 | -keyout key.pem \ 5 | -newkey ec \ 6 | -pkeyopt ec_paramgen_curve:prime256v1 \ 7 | -subj '/CN=127.0.0.1' \ 8 | -days 14 9 | -------------------------------------------------------------------------------- /examples/webtransport/open_chrome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | HASH=`openssl x509 -pubkey -noout -in cert.pem | 3 | openssl pkey -pubin -outform der | 4 | openssl dgst -sha256 -binary | 5 | base64` 6 | 7 | /opt/google/chrome/chrome \ 8 | --origin-to-force-quic-on=127.0.0.1:3000 \ 9 | --ignore-certificate-errors-spki-list=$HASH \ 10 | https://localhost:3000 11 | -------------------------------------------------------------------------------- /examples/webtransport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtransport", 3 | "version": "0.0.1", 4 | "description": "", 5 | "private": true, 6 | "type": "module", 7 | "dependencies": { 8 | "@fails-components/webtransport": "^1.0.8", 9 | "@fails-components/webtransport-transport-http3-quiche": "^1.0.8", 10 | "socket.io": "^4.7.4" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/whiteboard/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Socket.IO Collaborative Whiteboard 3 | 4 | A simple collaborative whiteboard for Socket.IO 5 | 6 | ## How to use 7 | 8 | ``` 9 | $ npm ci && npm start 10 | ``` 11 | 12 | And point your browser to `http://localhost:3000`. Optionally, specify 13 | a port by supplying the `PORT` env variable. 14 | 15 | ## Features 16 | 17 | - draw on the whiteboard and all other users will see you drawings live 18 | -------------------------------------------------------------------------------- /examples/whiteboard/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const http = require('http').Server(app); 5 | const io = require('socket.io')(http); 6 | const port = process.env.PORT || 3000; 7 | 8 | app.use(express.static(__dirname + '/public')); 9 | 10 | function onConnection(socket){ 11 | socket.on('drawing', (data) => socket.broadcast.emit('drawing', data)); 12 | } 13 | 14 | io.on('connection', onConnection); 15 | 16 | http.listen(port, () => console.log('listening on port ' + port)); 17 | -------------------------------------------------------------------------------- /examples/whiteboard/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whiteboard", 3 | "version": "1.0.0", 4 | "description": "A simple collaborative whiteboard using socket.io", 5 | "main": "index.js", 6 | "keywords": [ 7 | "socket.io", 8 | "whiteboard" 9 | ], 10 | "dependencies": { 11 | "express": "~4.17.1", 12 | "socket.io": "^4.0.0" 13 | }, 14 | "scripts": { 15 | "start": "node index" 16 | }, 17 | "author": "Damien Arrachequesne", 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /examples/whiteboard/public/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <title>Socket.IO whiteboard</title> 6 | <link rel="stylesheet" href="style.css"> 7 | </head> 8 | <body> 9 | 10 | <canvas class="whiteboard" ></canvas> 11 | 12 | <div class="colors"> 13 | <div class="color black"></div> 14 | <div class="color red"></div> 15 | <div class="color green"></div> 16 | <div class="color blue"></div> 17 | <div class="color yellow"></div> 18 | </div> 19 | 20 | <script src="/socket.io/socket.io.js"></script> 21 | <script src="/main.js"></script> 22 | </body> 23 | </html> -------------------------------------------------------------------------------- /examples/whiteboard/public/style.css: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Fix user-agent 4 | */ 5 | 6 | * { 7 | box-sizing: border-box; 8 | } 9 | 10 | html, body { 11 | height: 100%; 12 | margin: 0; 13 | padding: 0; 14 | } 15 | 16 | /** 17 | * Canvas 18 | */ 19 | 20 | .whiteboard { 21 | height: 100%; 22 | width: 100%; 23 | position: absolute; 24 | left: 0; 25 | right: 0; 26 | bottom: 0; 27 | top: 0; 28 | } 29 | 30 | .colors { 31 | position: fixed; 32 | } 33 | 34 | .color { 35 | display: inline-block; 36 | height: 48px; 37 | width: 48px; 38 | } 39 | 40 | .color.black { background-color: black; } 41 | .color.red { background-color: red; } 42 | .color.green { background-color: green; } 43 | .color.blue { background-color: blue; } 44 | .color.yellow { background-color: yellow; } 45 | -------------------------------------------------------------------------------- /packages/engine.io-client/.gitignore: -------------------------------------------------------------------------------- 1 | test/support/public/engine.io.min.js 2 | -------------------------------------------------------------------------------- /packages/engine.io-client/.prettierignore: -------------------------------------------------------------------------------- 1 | test/support/public/engine.io.min.js 2 | lib/contrib/* 3 | -------------------------------------------------------------------------------- /packages/engine.io-client/lib/browser-entrypoint.ts: -------------------------------------------------------------------------------- 1 | import { Socket } from "./socket.js"; 2 | 3 | export default (uri, opts) => new Socket(uri, opts); 4 | -------------------------------------------------------------------------------- /packages/engine.io-client/lib/contrib/has-cors.ts: -------------------------------------------------------------------------------- 1 | // imported from https://github.com/component/has-cors 2 | let value = false; 3 | 4 | try { 5 | value = typeof XMLHttpRequest !== 'undefined' && 6 | 'withCredentials' in new XMLHttpRequest(); 7 | } catch (err) { 8 | // if XMLHttp support is disabled in IE then it will throw 9 | // when trying to create 10 | } 11 | 12 | export const hasCORS = value; 13 | -------------------------------------------------------------------------------- /packages/engine.io-client/lib/globals.ts: -------------------------------------------------------------------------------- 1 | export const nextTick = (() => { 2 | const isPromiseAvailable = 3 | typeof Promise === "function" && typeof Promise.resolve === "function"; 4 | if (isPromiseAvailable) { 5 | return (cb) => Promise.resolve().then(cb); 6 | } else { 7 | return (cb, setTimeoutFn) => setTimeoutFn(cb, 0); 8 | } 9 | })(); 10 | 11 | export const globalThisShim = (() => { 12 | if (typeof self !== "undefined") { 13 | return self; 14 | } else if (typeof window !== "undefined") { 15 | return window; 16 | } else { 17 | return Function("return this")(); 18 | } 19 | })(); 20 | 21 | export const defaultBinaryType = "arraybuffer"; 22 | 23 | export function createCookieJar() {} 24 | -------------------------------------------------------------------------------- /packages/engine.io-client/lib/index.ts: -------------------------------------------------------------------------------- 1 | import { Socket } from "./socket.js"; 2 | 3 | export { Socket }; 4 | export { 5 | SocketOptions, 6 | SocketWithoutUpgrade, 7 | SocketWithUpgrade, 8 | } from "./socket.js"; 9 | export const protocol = Socket.protocol; 10 | export { Transport, TransportError } from "./transport.js"; 11 | export { transports } from "./transports/index.js"; 12 | export { installTimerFunctions } from "./util.js"; 13 | export { parse } from "./contrib/parseuri.js"; 14 | export { nextTick } from "./globals.node.js"; 15 | 16 | export { Fetch } from "./transports/polling-fetch.js"; 17 | export { XHR as NodeXHR } from "./transports/polling-xhr.node.js"; 18 | export { XHR } from "./transports/polling-xhr.js"; 19 | export { WS as NodeWebSocket } from "./transports/websocket.node.js"; 20 | export { WS as WebSocket } from "./transports/websocket.js"; 21 | export { WT as WebTransport } from "./transports/webtransport.js"; 22 | -------------------------------------------------------------------------------- /packages/engine.io-client/lib/transports/index.ts: -------------------------------------------------------------------------------- 1 | import { XHR } from "./polling-xhr.node.js"; 2 | import { WS } from "./websocket.node.js"; 3 | import { WT } from "./webtransport.js"; 4 | 5 | export const transports = { 6 | websocket: WS, 7 | webtransport: WT, 8 | polling: XHR, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/engine.io-client/lib/transports/polling-xhr.node.ts: -------------------------------------------------------------------------------- 1 | import * as XMLHttpRequestModule from "xmlhttprequest-ssl"; 2 | import { BaseXHR, Request, RequestOptions } from "./polling-xhr.js"; 3 | 4 | const XMLHttpRequest = XMLHttpRequestModule.default || XMLHttpRequestModule; 5 | 6 | /** 7 | * HTTP long-polling based on the `XMLHttpRequest` object provided by the `xmlhttprequest-ssl` package. 8 | * 9 | * Usage: Node.js, Deno (compat), Bun (compat) 10 | * 11 | * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest 12 | */ 13 | export class XHR extends BaseXHR { 14 | request(opts: Record<string, any> = {}) { 15 | Object.assign( 16 | opts, 17 | { xd: this.xd, cookieJar: this.socket?._cookieJar }, 18 | this.opts, 19 | ); 20 | return new Request( 21 | (opts) => new XMLHttpRequest(opts), 22 | this.uri(), 23 | opts as RequestOptions, 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/engine.io-client/postcompile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cp ./support/package.cjs.json ./build/cjs/package.json 4 | cp ./support/package.esm.json ./build/esm/package.json 5 | 6 | cp -r ./build/esm/ ./build/esm-debug/ 7 | 8 | if [ "${OSTYPE:0:6}" = darwin ]; then 9 | sed -i '' -e '/debug(/d' ./build/esm/*.js ./build/esm/**/*.js 10 | else 11 | sed -i -e '/debug(/d' ./build/esm/*.js ./build/esm/**/*.js 12 | fi 13 | -------------------------------------------------------------------------------- /packages/engine.io-client/support/package.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine.io-client", 3 | "type": "commonjs", 4 | "browser": { 5 | "ws": false, 6 | "./transports/polling-xhr.node.js": "./transports/polling-xhr.js", 7 | "./transports/websocket.node.js": "./transports/websocket.js", 8 | "./globals.node.js": "./globals.js" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine.io-client/support/package.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine.io-client", 3 | "type": "module", 4 | "browser": { 5 | "ws": false, 6 | "./transports/polling-xhr.node.js": "./transports/polling-xhr.js", 7 | "./transports/websocket.node.js": "./transports/websocket.js", 8 | "./globals.node.js": "./globals.js" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine.io-client/support/prod.config.js: -------------------------------------------------------------------------------- 1 | const config = require("./webpack.config"); 2 | 3 | module.exports = { 4 | ...config, 5 | output: { 6 | ...config.output, 7 | filename: "engine.io.min.js", 8 | }, 9 | mode: "production", 10 | module: { 11 | rules: [ 12 | ...config.module.rules, 13 | { 14 | test: /\.js$/, 15 | loader: "webpack-remove-debug", 16 | }, 17 | ], 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/engine.io-client/support/rollup.config.esm.js: -------------------------------------------------------------------------------- 1 | const { nodeResolve } = require("@rollup/plugin-node-resolve"); 2 | const { terser } = require("rollup-plugin-terser"); 3 | 4 | const version = require("../package.json").version; 5 | const banner = `/*! 6 | * Engine.IO v${version} 7 | * (c) 2014-${new Date().getFullYear()} Guillermo Rauch 8 | * Released under the MIT License. 9 | */`; 10 | 11 | module.exports = { 12 | input: "./build/esm/index.js", 13 | output: { 14 | file: "./dist/engine.io.esm.min.js", 15 | format: "esm", 16 | sourcemap: true, 17 | plugins: [ 18 | terser({ 19 | mangle: { 20 | properties: { 21 | regex: /^_/, 22 | }, 23 | }, 24 | }), 25 | ], 26 | banner, 27 | }, 28 | plugins: [ 29 | nodeResolve({ 30 | browser: true, 31 | }), 32 | ], 33 | }; 34 | -------------------------------------------------------------------------------- /packages/engine.io-client/support/webpack.config.js: -------------------------------------------------------------------------------- 1 | const { BannerPlugin } = require("webpack"); 2 | const version = require("../package.json").version; 3 | 4 | const banner = `Engine.IO v${version} 5 | (c) 2014-${new Date().getFullYear()} Guillermo Rauch 6 | Released under the MIT License.`; 7 | 8 | module.exports = { 9 | entry: "./build/esm/index.js", 10 | output: { 11 | filename: "engine.io.js", 12 | library: "eio", 13 | libraryTarget: "umd", 14 | globalObject: "self", 15 | }, 16 | mode: "development", 17 | node: false, 18 | module: { 19 | rules: [ 20 | { 21 | test: /\.m?js$/, 22 | use: { 23 | loader: "babel-loader", 24 | options: { 25 | presets: ["@babel/preset-env"], 26 | plugins: ["@babel/plugin-transform-object-assign"], 27 | }, 28 | }, 29 | }, 30 | ], 31 | }, 32 | plugins: [new BannerPlugin(banner)], 33 | }; 34 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/arraybuffer/index.js: -------------------------------------------------------------------------------- 1 | const env = require("../support/env"); 2 | 3 | require("./polling.js"); 4 | if (env.wsSupport && !env.isOldSimulator && !env.isAndroid && !env.isIE11) { 5 | require("./ws.js"); 6 | } 7 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/binary-fallback.js: -------------------------------------------------------------------------------- 1 | const expect = require("expect.js"); 2 | const eio = require("../"); 3 | 4 | describe("binary fallback", function () { 5 | this.timeout(10000); 6 | 7 | it("should be able to receive binary data when ArrayBuffer not available (polling)", (done) => { 8 | const socket = new eio.Socket({ forceBase64: true }); 9 | socket.on("open", () => { 10 | socket.send("give binary"); 11 | let firstPacket = true; 12 | socket.on("message", (data) => { 13 | if (firstPacket) { 14 | firstPacket = false; 15 | return; 16 | } 17 | 18 | expect(data.base64).to.be(true); 19 | expect(data.data).to.equal("AAECAwQ="); 20 | 21 | socket.close(); 22 | done(); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/blob/index.js: -------------------------------------------------------------------------------- 1 | const env = require("../support/env"); 2 | 3 | require("./polling.js"); 4 | if (env.wsSupport && !env.isOldSimulator && !env.isAndroid && !env.isIE11) { 5 | require("./ws.js"); 6 | } 7 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/fixtures/no-unref.js: -------------------------------------------------------------------------------- 1 | const { Socket } = require("../.."); 2 | const socket = new Socket("http://localhost:3000", { 3 | autoUnref: false, 4 | }); 5 | 6 | setTimeout(() => { 7 | console.log("process should not exit"); 8 | }, 50); 9 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/fixtures/unref-polling-only.js: -------------------------------------------------------------------------------- 1 | const { Socket } = require("../.."); 2 | const socket = new Socket("http://localhost:3000", { 3 | autoUnref: true, 4 | transports: ["polling"], 5 | }); 6 | 7 | socket.on("open", () => { 8 | console.log("open"); 9 | }); 10 | 11 | setTimeout(() => { 12 | console.log("process should exit now"); 13 | }, 50); 14 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/fixtures/unref-websocket-only.js: -------------------------------------------------------------------------------- 1 | const { Socket } = require("../.."); 2 | const socket = new Socket("http://localhost:3000", { 3 | autoUnref: true, 4 | transports: ["websocket"], 5 | }); 6 | 7 | socket.on("open", () => { 8 | console.log("open"); 9 | }); 10 | 11 | setTimeout(() => { 12 | console.log("process should exit now"); 13 | }, 50); 14 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/fixtures/unref.js: -------------------------------------------------------------------------------- 1 | const { Socket } = require("../.."); 2 | const socket = new Socket("http://localhost:3000", { 3 | autoUnref: true, 4 | }); 5 | 6 | socket.on("open", () => { 7 | console.log("open"); 8 | }); 9 | 10 | setTimeout(() => { 11 | console.log("process should exit now"); 12 | }, 50); 13 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/index.js: -------------------------------------------------------------------------------- 1 | const env = require("./support/env"); 2 | 3 | // whitelist some globals to avoid warnings 4 | if (env.browser) { 5 | window.___eio = null; 6 | } else { 7 | require("./node"); 8 | } 9 | 10 | require("./engine.io-client"); 11 | require("./socket"); 12 | require("./transport"); 13 | require("./connection"); 14 | require("./xmlhttprequest"); 15 | require("./parseuri"); 16 | 17 | if (typeof ArrayBuffer !== "undefined") { 18 | require("./arraybuffer"); 19 | } else { 20 | require("./binary-fallback"); 21 | } 22 | 23 | // Blob is available in Node.js since v18, but not yet supported by the `engine.io-parser` package 24 | if (typeof Blob === "function" && env.browser) { 25 | require("./blob"); 26 | } 27 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/support/public/worker.js: -------------------------------------------------------------------------------- 1 | /* global importScripts,eio,postMessage */ 2 | 3 | importScripts("/test/support/engine.io.min.js"); 4 | 5 | var socket = eio(); 6 | 7 | var count = 0; 8 | socket.on("message", function (msg) { 9 | count++; 10 | if (count < 10) { 11 | socket.send("give utf8"); 12 | } else if (count < 20) { 13 | socket.send("give binary"); 14 | } 15 | postMessage(msg); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/engine.io-client/test/util.js: -------------------------------------------------------------------------------- 1 | // polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat 2 | exports.repeat = function (str, count) { 3 | if (String.prototype.repeat) { 4 | return str.repeat(count); 5 | } 6 | const maxCount = str.length * count; 7 | count = Math.floor(Math.log(count) / Math.log(2)); 8 | while (count) { 9 | str += str; 10 | count--; 11 | } 12 | str += str.substring(0, maxCount - str.length); 13 | return str; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/engine.io-client/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/esm/", 4 | "target": "es2018", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "declaration": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/engine.io-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/cjs/", 4 | "target": "es2018", // Node.js 10 (https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping) 5 | "module": "commonjs", 6 | "declaration": true, 7 | "esModuleInterop": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/engine.io-parser/.prettierignore: -------------------------------------------------------------------------------- 1 | lib/contrib/* 2 | -------------------------------------------------------------------------------- /packages/engine.io-parser/postcompile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp ./support/package.cjs.json ./build/cjs/package.json 4 | cp ./support/package.esm.json ./build/esm/package.json 5 | -------------------------------------------------------------------------------- /packages/engine.io-parser/support/package.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine.io-parser", 3 | "type": "commonjs", 4 | "browser": { 5 | "./encodePacket.js": "./encodePacket.browser.js", 6 | "./decodePacket.js": "./decodePacket.browser.js" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine.io-parser/support/package.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine.io-parser", 3 | "type": "module", 4 | "browser": { 5 | "./encodePacket.js": "./encodePacket.browser.js", 6 | "./decodePacket.js": "./decodePacket.browser.js" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine.io-parser/test.js: -------------------------------------------------------------------------------- 1 | const parser = require('.'); 2 | 3 | parser.encodePayload([ 4 | { 5 | type: 'message', 6 | data: '€', 7 | }, 8 | { 9 | type: 'message', 10 | data: Buffer.from([1, 2, 3, 4]), 11 | }, 12 | ], true, console.log); 13 | -------------------------------------------------------------------------------- /packages/engine.io-parser/test/util.ts: -------------------------------------------------------------------------------- 1 | const areArraysEqual = (x, y) => { 2 | if (x.byteLength !== y.byteLength) return false; 3 | const xView = new Uint8Array(x), 4 | yView = new Uint8Array(y); 5 | for (let i = 0; i < x.byteLength; i++) { 6 | if (xView[i] !== yView[i]) return false; 7 | } 8 | return true; 9 | }; 10 | 11 | const createArrayBuffer = (array) => { 12 | // Uint8Array.from() is not defined in IE 10/11 13 | const arrayBuffer = new ArrayBuffer(array.length); 14 | const view = new Uint8Array(arrayBuffer); 15 | for (let i = 0; i < array.length; i++) { 16 | view[i] = array[i]; 17 | } 18 | return arrayBuffer; 19 | }; 20 | 21 | export { areArraysEqual, createArrayBuffer }; 22 | -------------------------------------------------------------------------------- /packages/engine.io-parser/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/esm/", 4 | "target": "es2018", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "declaration": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/engine.io-parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/cjs/", 4 | "target": "es2018", // Node.js 10 (https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping) 5 | "module": "commonjs", 6 | "declaration": true 7 | }, 8 | "include": [ 9 | "./lib/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine.io/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "prettier", 3 | "parser": "babel-eslint" 4 | } 5 | -------------------------------------------------------------------------------- /packages/engine.io/.prettierignore: -------------------------------------------------------------------------------- 1 | lib/parser-v3/ 2 | -------------------------------------------------------------------------------- /packages/engine.io/examples/esm-import/README.md: -------------------------------------------------------------------------------- 1 | ## How to use 2 | 3 | ``` 4 | $ npm link ../.. 5 | $ node index.js 6 | ``` 7 | -------------------------------------------------------------------------------- /packages/engine.io/examples/esm-import/index.js: -------------------------------------------------------------------------------- 1 | import { Server } from "engine.io"; 2 | 3 | console.log(Server); 4 | -------------------------------------------------------------------------------- /packages/engine.io/examples/esm-import/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm-import", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module" 6 | } 7 | -------------------------------------------------------------------------------- /packages/engine.io/examples/latency/README.md: -------------------------------------------------------------------------------- 1 | 2 | # eio-latency 3 | 4 | ## Running 5 | 6 | First, execute: 7 | 8 | ``` 9 | $ npm install 10 | ``` 11 | 12 | Then execute the server: 13 | 14 | ``` 15 | $ node index 16 | ``` 17 | 18 | And point your browser to `localhost:3000` (if PORT is set in your environment, then it will use that instead). 19 | -------------------------------------------------------------------------------- /packages/engine.io/examples/latency/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html> 3 | <head> 4 | <title>EIO Latency</title> 5 | <link rel="stylesheet" href="/style.css" /> 6 | </head> 7 | <body> 8 | <h1>EIO Latency <span id="latency"></span></h1> 9 | <h2 id="transport">(connecting)</h2> 10 | <canvas id="chart" height="200"></canvas> 11 | 12 | <script src="/engine.io.min.js"></script> 13 | <script src="/index.js"></script> 14 | </body> 15 | </html> 16 | -------------------------------------------------------------------------------- /packages/engine.io/examples/latency/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | const express = require('express'); 7 | const app = express(); 8 | const server = require('http').createServer(app); 9 | const enchilada = require('enchilada'); 10 | const io = require('engine.io').attach(server); 11 | 12 | app.use(enchilada({ 13 | src: __dirname + '/public', 14 | debug: true 15 | })); 16 | app.use(express.static(__dirname + '/public')); 17 | app.get('/', (req, res) => { 18 | res.sendFile(__dirname + '/index.html'); 19 | }); 20 | 21 | app.get('/engine.io.min.js', (req, res) => { 22 | res.sendFile(require.resolve('engine.io-client/dist/engine.io.min.js')); 23 | }); 24 | 25 | io.on('connection', (socket) => { 26 | socket.on('message', () => { 27 | socket.send('pong'); 28 | }); 29 | }); 30 | 31 | const port = process.env.PORT || 3000; 32 | server.listen(port, () => { 33 | console.log('\x1B[96mlistening on localhost:' + port + ' \x1B[39m'); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/engine.io/examples/latency/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eio-latency", 3 | "version": "0.1.0", 4 | "dependencies": { 5 | "enchilada": "0.13.0", 6 | "engine.io": "^6.4.2", 7 | "engine.io-client": "^4.1.4", 8 | "express": "^4.19.2", 9 | "smoothie": "1.19.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine.io/examples/latency/public/style.css: -------------------------------------------------------------------------------- 1 | 2 | body { margin: 0; padding: 0; font-family: Helvetica Neue; } 3 | h1 { margin: 100px 100px 10px; } 4 | h2 { color: #999; margin: 0 100px 30px; font-weight: normal; } 5 | #latency { color: red; } 6 | -------------------------------------------------------------------------------- /packages/engine.io/examples/memory-usage-webtransport/.gitignore: -------------------------------------------------------------------------------- 1 | *.pem 2 | *.log 3 | -------------------------------------------------------------------------------- /packages/engine.io/examples/memory-usage-webtransport/generate_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | openssl req -new -x509 -nodes \ 3 | -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \ 4 | -days 14 \ 5 | -out cert.pem -keyout key.pem \ 6 | -subj '/CN=127.0.0.1' 7 | -------------------------------------------------------------------------------- /packages/engine.io/examples/memory-usage-webtransport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "memory-usage-webtransport", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "", 6 | "type": "module", 7 | "dependencies": { 8 | "@fails-components/webtransport": "^0.3.1", 9 | "engine.io-client": "^6.5.3" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine.io/examples/memory-usage/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /packages/engine.io/examples/memory-usage/client.js: -------------------------------------------------------------------------------- 1 | import { Socket } from "engine.io-client"; 2 | 3 | const CLIENTS_COUNT = 100; 4 | 5 | for (let i = 0; i < CLIENTS_COUNT; i++) { 6 | const socket = new Socket("ws://localhost:3000", { 7 | transports: ["websocket"], 8 | }); 9 | 10 | socket.on("open", () => {}); 11 | 12 | socket.on("message", () => {}); 13 | 14 | socket.on("close", (reason) => {}); 15 | } 16 | -------------------------------------------------------------------------------- /packages/engine.io/examples/memory-usage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "memory-usage", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "", 6 | "type": "module", 7 | "dependencies": { 8 | "engine.io-client": "^6.5.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine.io/lib/transports-uws/index.ts: -------------------------------------------------------------------------------- 1 | import { Polling } from "./polling"; 2 | import { WebSocket } from "./websocket"; 3 | 4 | export default { 5 | polling: Polling, 6 | websocket: WebSocket, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/engine.io/lib/transports/index.ts: -------------------------------------------------------------------------------- 1 | import { Polling as XHR } from "./polling"; 2 | import { JSONP } from "./polling-jsonp"; 3 | import { WebSocket } from "./websocket"; 4 | import { WebTransport } from "./webtransport"; 5 | 6 | export default { 7 | polling: polling, 8 | websocket: WebSocket, 9 | webtransport: WebTransport, 10 | }; 11 | 12 | /** 13 | * Polling polymorphic constructor. 14 | */ 15 | 16 | function polling(req) { 17 | if ("string" === typeof req._query.j) { 18 | return new JSONP(req); 19 | } else { 20 | return new XHR(req); 21 | } 22 | } 23 | 24 | polling.upgradesTo = ["websocket", "webtransport"]; 25 | -------------------------------------------------------------------------------- /packages/engine.io/test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/client.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBrTCCARYCAQAwbTELMAkGA1UEBhMCRkkxEzARBgNVBAgTClNvbWUtU3RhdGUx 3 | ETAPBgNVBAcTCEhlbHNpbmtpMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 4 | eSBMdGQxEzARBgNVBAMTCkZvbyBDbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A 5 | MIGJAoGBAPrpGfw/w74wrXew/EggQwdcNFmF5EuoY2U2xfNoEtacpKVX5bGLU50K 6 | Ka0CHhkBVG3UmQr2ZAQAZ3ELxNHAMxLTb4RQrUfXO+HvsSThlwdbynkJUSbncVOY 7 | 76OEv7sFBhdbXKL9dREG/bGbdD3kjvz3lqCmswUjweI678d2L+INAgMBAAGgADAN 8 | BgkqhkiG9w0BAQUFAAOBgQDKGUqjkUxGOisFN70X7ZOW7H99veR9QlixKl5e0W+7 9 | UtJ+GUtH2WQEb4F72+ruHrdDWQI1VaH9hPOvTRCjlgXiT0RHXpGPbJK/Nc+Eq5dm 10 | kuk/tQeXv6+S1fgYOm0w09rE7pBjQtuAybB55lGZ7k84UE2xTc97Ru14nYFCsZ4z 11 | RA== 12 | -----END CERTIFICATE REQUEST----- 13 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQD66Rn8P8O+MK13sPxIIEMHXDRZheRLqGNlNsXzaBLWnKSlV+Wx 3 | i1OdCimtAh4ZAVRt1JkK9mQEAGdxC8TRwDMS02+EUK1H1zvh77Ek4ZcHW8p5CVEm 4 | 53FTmO+jhL+7BQYXW1yi/XURBv2xm3Q95I7895agprMFI8HiOu/Hdi/iDQIDAQAB 5 | AoGBAOFHTXd4YO1wky82Dy1LGiOPm8kNOC7d33BOv2iN9uwN9J4nzymbqNUE/OpD 6 | TnaxBPcfvNFk6+PT4QxUvsB8ytzDMZ3YC4xyJf5GPP/hfzyWCRjB557WZl1cx7nC 7 | 2gA93PBZE7WT1SySXmjsiC7o/2T/0cUaawXOBczHP8oXoEkBAkEA/c1MHs13ojxh 8 | oOj/ibCpYpd2Zv5Hrc5tsh+otDdIrb79IAHnNw7WhMkLs6cLk1MY6jLeCvQtjlUY 9 | H5C/6Ez84QJBAP0VZMgWPw3FVNXPrj833OA6XjyWO+TADpnlrahuDQqWnR3C29Uc 10 | Iq/ApVX2pt2cNIZpiuJ4BYNc44cHjvu6vq0CQQChan1cJc9NhluNLELBfnLsOmpa 11 | bKSH3P8VR19TZsm5fvub7Lnx4WT7xKXFl5scEsCIyts/WjbTDDmwca4r/zLhAkB4 12 | wkeHbY4CnSDgsKr9AUPEPjWPBURo3vdYmY4mKvTQE5O+iqboZfdrEyoQ/ZMbdRhe 13 | 9mdNrmU7DAyI9qNUHAQ1AkAlq/vdkrcq5SRR9uti/1M0/Jaw7l3JutBaW93kdvXx 14 | BX568ezO1PQtXwVSv+uJEkDoST1bkvhqt7hlMu/RkmfG 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/client.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/packages/engine.io/test/fixtures/client.pfx -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/server-close-upgraded.js: -------------------------------------------------------------------------------- 1 | const { ClientSocket, listen } = require("../common"); 2 | 3 | const engine = listen((port) => { 4 | const socket = new ClientSocket("ws://localhost:" + port); 5 | socket.on("upgrade", () => { 6 | engine.httpServer.close(); 7 | engine.close(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/server-close-upgrading.js: -------------------------------------------------------------------------------- 1 | const { ClientSocket, listen } = require("../common"); 2 | 3 | const engine = listen((port) => { 4 | const socket = new ClientSocket("ws://localhost:" + port); 5 | socket.on("upgrading", () => { 6 | engine.httpServer.close(); 7 | engine.close(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/server-close.js: -------------------------------------------------------------------------------- 1 | const { ClientSocket, listen } = require("../common"); 2 | 3 | const engine = listen((port) => { 4 | const socket = new ClientSocket("ws://localhost:" + port); 5 | socket.on("open", () => { 6 | engine.httpServer.close(); 7 | engine.close(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/server.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBrDCCARUCAQAwbDELMAkGA1UEBhMCRkkxEzARBgNVBAgTClNvbWUtU3RhdGUx 3 | ETAPBgNVBAcTCEhlbHNpbmtpMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 4 | eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw 5 | gYkCgYEAwECzTwyC6jCLpbz4GuqIHIuvcWGkqedFO07/B8MN5uA/cNrm8hqke3Q1 6 | ttIhiSO7UzXL/1LS6oJJxIggV5KvzA6+YHVzSNFf4/qgDqnyUlcb8cR8S67e4r46 7 | WR2zuwdyu25FpgsQBc1gJROVPRV19W/FX3rSb/nAxGl7GMLmH6MCAwEAAaAAMA0G 8 | CSqGSIb3DQEBBQUAA4GBAClj/K2DAH5S64T6s7jervmk4N956Ho3aTLBgE+ReXLj 9 | btcTdk3vFbQApAlG6MrSKys4HjpKpP/RENx3Js0HHeb8ELmWtIQNxRhwIpl0K5AD 10 | xorKj+mwngLtVyARb/M7O3E8jYHzBPzpsolKWIY4AavYdmHu+Zhgm4hPKUcW+bAv 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /packages/engine.io/test/fixtures/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXgIBAAKBgQDAQLNPDILqMIulvPga6ogci69xYaSp50U7Tv8Hww3m4D9w2uby 3 | GqR7dDW20iGJI7tTNcv/UtLqgknEiCBXkq/MDr5gdXNI0V/j+qAOqfJSVxvxxHxL 4 | rt7ivjpZHbO7B3K7bkWmCxAFzWAlE5U9FXX1b8VfetJv+cDEaXsYwuYfowIDAQAB 5 | AoGBAL7tQmXl2fmz/mu5kHhCpKwcuT6TpxEo4aN132aY+qxn1flBHAwiE2mbTmDi 6 | rHViq/2GNrK5UUed3p60RdJSlgwIkyqtcGxWhUJGYCR/hU60qeeLp3MhhOoOFbiV 7 | YTDsoC7V/SuWbX+1qG5FxnHSnTZhAIRkZXS4uTZ5WDcQm/7BAkEA+TlZ1IT9CeU/ 8 | FpHpqc8RgR8377Ehjy8o4Z4EGFnxQlAUWASnhs6dw4isr3+c7hA1OEmqmcRClPVZ 9 | t1JbHAPC4QJBAMV60WSJzPUccCF47T9Ao2CeWFl/9dmgQQe9idpTNuKMXNtPJN44 10 | 0MQvnb+xS828woJOoRI+/UTVLLBc4xwMtwMCQQDZTadExTw4v5l1nX5GoJUbp9PG 11 | /ARN64nSx0u8y9evwVErucs0oL0we+BOGZAEhz9QN/M3pceESDWUwYtNbv4hAkBB 12 | Ku2MqvjK7k6GjTxlgjQn/zkSl+qOnZa4MjEarhlPm5hM+wokl0U1aK07BAwK4b6i 13 | d8YpmkXEAEEWFiEQMZX3AkEA1SkdiFj1u7HnzO7onLJsnFzowX3pm1UFl0azOMlM 14 | 2GkjYxWeJ/4VL7Y6QkhHE0Nj3my2+MJQI9xpYgMbw/l11w== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /packages/engine.io/test/parser.js: -------------------------------------------------------------------------------- 1 | const expect = require("expect.js"); 2 | const parser = require("../build/parser-v3/index.js"); 3 | 4 | describe("parser", () => { 5 | it("properly encodes a mixed payload", (done) => { 6 | parser.encodePayload( 7 | [ 8 | { type: "message", data: "€€€€" }, 9 | { type: "message", data: Buffer.from([1, 2, 3]) }, 10 | ], 11 | true, 12 | (encoded) => { 13 | expect(encoded).to.be.a(Buffer); 14 | 15 | parser.decodePayload(encoded, (decoded) => { 16 | expect(decoded.data).to.eql("€€€€"); 17 | done(); 18 | }); 19 | }, 20 | ); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/engine.io/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/", 4 | "target": "es2018", // Node.js 10 (https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping) 5 | "module": "commonjs", 6 | "declaration": true 7 | }, 8 | "include": [ 9 | "./lib/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine.io/wrapper.mjs: -------------------------------------------------------------------------------- 1 | export { 2 | Server, 3 | Socket, 4 | Transport, 5 | transports, 6 | listen, 7 | attach, 8 | parser, 9 | protocol, 10 | } from "./build/engine.io.js"; 11 | -------------------------------------------------------------------------------- /packages/socket.io-adapter/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # socket.io-adapter 3 | 4 | Default socket.io in-memory adapter class. 5 | 6 | Compatibility table: 7 | 8 | | Adapter version | Socket.IO server version | 9 | |-----------------| ------------------------ | 10 | | 1.x.x | 1.x.x / 2.x.x | 11 | | 2.x.x | 3.x.x | 12 | 13 | ## How to use 14 | 15 | This module is not intended for end-user usage, but can be used as an 16 | interface to inherit from other adapters you might want to build. 17 | 18 | As an example of an adapter that builds on top of this, please take a look 19 | at [socket.io-redis](https://github.com/learnboost/socket.io-redis). 20 | 21 | ## License 22 | 23 | MIT 24 | -------------------------------------------------------------------------------- /packages/socket.io-adapter/lib/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | SocketId, 3 | PrivateSessionId, 4 | Room, 5 | BroadcastFlags, 6 | BroadcastOptions, 7 | Session, 8 | Adapter, 9 | SessionAwareAdapter, 10 | } from "./in-memory-adapter"; 11 | 12 | export { 13 | ClusterAdapter, 14 | ClusterAdapterWithHeartbeat, 15 | ClusterAdapterOptions, 16 | ClusterMessage, 17 | ClusterResponse, 18 | MessageType, 19 | ServerId, 20 | Offset, 21 | } from "./cluster-adapter"; 22 | -------------------------------------------------------------------------------- /packages/socket.io-adapter/test/util.ts: -------------------------------------------------------------------------------- 1 | export function times(count: number, fn: () => void) { 2 | let i = 0; 3 | return () => { 4 | i++; 5 | if (i === count) { 6 | fn(); 7 | } else if (i > count) { 8 | throw new Error(`too many calls: ${i} instead of ${count}`); 9 | } 10 | }; 11 | } 12 | 13 | export function shouldNotHappen(done) { 14 | return () => done(new Error("should not happen")); 15 | } 16 | 17 | export function sleep() { 18 | return new Promise<void>((resolve) => process.nextTick(resolve)); 19 | } 20 | -------------------------------------------------------------------------------- /packages/socket.io-adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "allowJs": false, 5 | "target": "es2017", 6 | "module": "commonjs", 7 | "declaration": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/socket.io-client/.prettierignore: -------------------------------------------------------------------------------- 1 | lib/contrib/* 2 | -------------------------------------------------------------------------------- /packages/socket.io-client/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [["@babel/preset-env"]], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/socket.io-client/docs/README.md: -------------------------------------------------------------------------------- 1 | 2 | The documentation has been moved to the website [here](https://socket.io/docs/). 3 | -------------------------------------------------------------------------------- /packages/socket.io-client/lib/browser-entrypoint.ts: -------------------------------------------------------------------------------- 1 | import { io } from "./index.js"; 2 | 3 | export default io; 4 | -------------------------------------------------------------------------------- /packages/socket.io-client/lib/on.ts: -------------------------------------------------------------------------------- 1 | import { Emitter } from "@socket.io/component-emitter"; 2 | 3 | export function on( 4 | obj: Emitter<any, any>, 5 | ev: string, 6 | fn: (err?: any) => any, 7 | ): VoidFunction { 8 | obj.on(ev, fn); 9 | return function subDestroy(): void { 10 | obj.off(ev, fn); 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /packages/socket.io-client/postcompile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp ./support/package.esm.json ./build/esm/package.json 4 | 5 | cp -r ./build/esm/ ./build/esm-debug/ 6 | 7 | if [[ "$OSTYPE" == "darwin"* ]]; then 8 | sed -i '' -e '/debug(/d' ./build/esm/*.js 9 | else 10 | sed -i -e '/debug(/d' ./build/esm/*.js 11 | fi 12 | 13 | # for backward compatibility with `const socket = require("socket.io-client")(...)` 14 | echo -e '\nmodule.exports = lookup;' >> ./build/cjs/index.js 15 | -------------------------------------------------------------------------------- /packages/socket.io-client/support/package.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-client", 3 | "version": "4.7.5", 4 | "type": "module" 5 | } 6 | -------------------------------------------------------------------------------- /packages/socket.io-client/support/rollup.config.esm.js: -------------------------------------------------------------------------------- 1 | const { nodeResolve } = require("@rollup/plugin-node-resolve"); 2 | const commonjs = require("@rollup/plugin-commonjs"); 3 | const { terser } = require("rollup-plugin-terser"); 4 | 5 | const version = require("../package.json").version; 6 | const banner = `/*! 7 | * Socket.IO v${version} 8 | * (c) 2014-${new Date().getFullYear()} Guillermo Rauch 9 | * Released under the MIT License. 10 | */`; 11 | 12 | module.exports = { 13 | input: "./build/esm/index.js", 14 | output: { 15 | file: "./dist/socket.io.esm.min.js", 16 | format: "esm", 17 | sourcemap: true, 18 | plugins: [ 19 | terser({ 20 | mangle: { 21 | properties: { 22 | regex: /^_/, 23 | }, 24 | }, 25 | }), 26 | ], 27 | banner, 28 | }, 29 | plugins: [ 30 | nodeResolve({ 31 | browser: true, 32 | }), 33 | commonjs(), 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /packages/socket.io-client/support/rollup.config.umd.msgpack.js: -------------------------------------------------------------------------------- 1 | const base = require("./rollup.config.umd.js")[1]; 2 | const alias = require("@rollup/plugin-alias"); 3 | const commonjs = require("@rollup/plugin-commonjs"); 4 | 5 | module.exports = { 6 | ...base, 7 | output: { 8 | ...base.output, 9 | file: "./dist/socket.io.msgpack.min.js", 10 | }, 11 | plugins: [ 12 | commonjs(), 13 | alias({ 14 | entries: [ 15 | { 16 | find: "socket.io-parser", 17 | replacement: "socket.io-msgpack-parser", 18 | }, 19 | ], 20 | }), 21 | ...base.plugins, 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true, 4 | "mocha": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/browser-runner.ts: -------------------------------------------------------------------------------- 1 | import { Launcher } from "@wdio/cli"; 2 | import { createServer } from "./support/server"; 3 | 4 | const launcher = new Launcher("./wdio.conf.js"); 5 | 6 | async function run() { 7 | const server = createServer(); 8 | 9 | try { 10 | const exitCode = await launcher.run(); 11 | server.close(); 12 | process.exit(exitCode); 13 | } catch (e) { 14 | console.error("Launcher failed to start the test", e.stacktrace); 15 | process.exit(1); 16 | } 17 | } 18 | 19 | run(); 20 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/fixtures/no-unref.ts: -------------------------------------------------------------------------------- 1 | const { io } = require("../.."); 2 | const socket = io("http://localhost:3211", { 3 | autoUnref: false, 4 | }); 5 | 6 | setTimeout(() => { 7 | console.log("process should not exit"); 8 | }, 50); 9 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/fixtures/unref-during-reconnection.ts: -------------------------------------------------------------------------------- 1 | const { io } = require("../.."); 2 | const socket = io("http://localhost:3211", { 3 | autoUnref: true, 4 | }); 5 | 6 | socket.on("open", () => { 7 | console.log("open"); 8 | }); 9 | 10 | setTimeout(() => { 11 | console.log("process should exit now"); 12 | }, 50); 13 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/fixtures/unref-polling-only.ts: -------------------------------------------------------------------------------- 1 | const { io } = require("../.."); 2 | const socket = io("http://localhost:3210", { 3 | autoUnref: true, 4 | transports: ["polling"], 5 | }); 6 | 7 | socket.on("open", () => { 8 | console.log("open"); 9 | }); 10 | 11 | setTimeout(() => { 12 | console.log("process should exit now"); 13 | }, 50); 14 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/fixtures/unref-websocket-only.ts: -------------------------------------------------------------------------------- 1 | const { io } = require("../.."); 2 | const socket = io("http://localhost:3210", { 3 | autoUnref: true, 4 | transports: ["websocket"], 5 | }); 6 | 7 | socket.on("open", () => { 8 | console.log("open"); 9 | }); 10 | 11 | setTimeout(() => { 12 | console.log("process should exit now"); 13 | }, 50); 14 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/fixtures/unref.ts: -------------------------------------------------------------------------------- 1 | const { io } = require("../.."); 2 | const socket = io("http://localhost:3210", { 3 | autoUnref: true, 4 | }); 5 | 6 | socket.on("open", () => { 7 | console.log("open"); 8 | }); 9 | 10 | setTimeout(() => { 11 | console.log("process should exit now"); 12 | }, 50); 13 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/index.ts: -------------------------------------------------------------------------------- 1 | import "./url"; 2 | import "./connection"; 3 | import "./socket"; 4 | import "./node"; 5 | import "./connection-state-recovery"; 6 | import "./retry"; 7 | -------------------------------------------------------------------------------- /packages/socket.io-client/test/support/hooks.ts: -------------------------------------------------------------------------------- 1 | import { createServer } from "./server"; 2 | 3 | let server; 4 | 5 | export const mochaHooks = { 6 | beforeAll() { 7 | server = createServer(); 8 | }, 9 | afterAll() { 10 | server.close(); 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/socket.io-client/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/esm/", 4 | "target": "es2018", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "declaration": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/socket.io-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/cjs/", 4 | "target": "es2018", // Node.js 10 (https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping) 5 | "module": "commonjs", 6 | "declaration": true, 7 | "esModuleInterop": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/socket.io-cluster-engine/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # History 2 | 3 | | Version | Release date | 4 | |--------------------------|--------------| 5 | | [0.1.0](#010-2024-07-17) | July 2024 | 6 | 7 | # Release notes 8 | 9 | ## `0.1.0` (2024-07-17) 10 | 11 | Initial release! 12 | -------------------------------------------------------------------------------- /packages/socket.io-cluster-engine/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | redis: 3 | image: redis:7 4 | ports: 5 | - "6379:6379" 6 | -------------------------------------------------------------------------------- /packages/socket.io-cluster-engine/lib/index.ts: -------------------------------------------------------------------------------- 1 | export { setupPrimary, NodeClusterEngine } from "./cluster"; 2 | export { setupPrimaryWithRedis, RedisEngine } from "./redis"; 3 | -------------------------------------------------------------------------------- /packages/socket.io-cluster-engine/test/util.ts: -------------------------------------------------------------------------------- 1 | import expect = require("expect.js"); 2 | 3 | export function url(port: number, sid?: string) { 4 | let url = `http://localhost:${port}/engine.io/?EIO=4&transport=polling`; 5 | if (sid) { 6 | url += `&sid=${sid}`; 7 | } 8 | return url; 9 | } 10 | 11 | export async function handshake(port: number) { 12 | const res = await fetch(url(port)); 13 | expect(res.status).to.eql(200); 14 | 15 | const body1 = await res.text(); 16 | return JSON.parse(body1.substring(1)).sid; 17 | } 18 | -------------------------------------------------------------------------------- /packages/socket.io-cluster-engine/test/worker.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require("node:http"); 2 | const { NodeClusterEngine } = require("../dist/cluster"); 3 | 4 | const httpServer = createServer(); 5 | const engine = new NodeClusterEngine({ 6 | pingInterval: 50 7 | }); 8 | 9 | engine.on("connection", socket => { 10 | socket.on("message", (val) => { 11 | socket.send(val); 12 | }); 13 | }); 14 | 15 | engine.attach(httpServer); 16 | httpServer.listen(3000); 17 | -------------------------------------------------------------------------------- /packages/socket.io-cluster-engine/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "module": "node16", 5 | "target": "ES2022", 6 | "declaration": true, 7 | "strict": false 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/socket.io-component-emitter/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emitter", 3 | "repo": "component/emitter", 4 | "description": "Event emitter", 5 | "keywords": [ 6 | "emitter", 7 | "events" 8 | ], 9 | "version": "1.3.0", 10 | "scripts": [ 11 | "index.js" 12 | ], 13 | "license": "MIT" 14 | } 15 | -------------------------------------------------------------------------------- /packages/socket.io-component-emitter/lib/cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@socket.io/component-emitter", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /packages/socket.io-component-emitter/lib/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@socket.io/component-emitter", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /packages/socket.io-component-emitter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@socket.io/component-emitter", 3 | "description": "Event emitter", 4 | "version": "3.1.2", 5 | "license": "MIT", 6 | "component": { 7 | "scripts": { 8 | "emitter/index.js": "index.js" 9 | } 10 | }, 11 | "main": "./lib/cjs/index.js", 12 | "module": "./lib/esm/index.js", 13 | "types": "./lib/cjs/index.d.ts", 14 | "homepage": "https://github.com/socketio/socket.io/tree/main/packages/socket.io-component-emitter#readme", 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/socketio/socket.io.git" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/socketio/socket.io/issues" 21 | }, 22 | "scripts": { 23 | "test": "mocha --require should --reporter spec" 24 | }, 25 | "files": [ 26 | "lib/" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/socket.io-parser/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [["@babel/preset-env"]], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/socket.io-parser/bench/results.md: -------------------------------------------------------------------------------- 1 | small json parse x 67,893 ops/sec ±4.30% (76 runs sampled) 2 | big json parse x 1,507 ops/sec ±1.72% (82 runs sampled) 3 | json with small binary parse x 62,367 ops/sec ±6.03% (74 runs sampled) 4 | json with big binary parse x 572 ops/sec ±1.25% (86 runs sampled) 5 | -------------------------------------------------------------------------------- /packages/socket.io-parser/postcompile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp ./support/package.cjs.json ./build/cjs/package.json 4 | cp ./support/package.esm.json ./build/esm/package.json 5 | 6 | cp -r ./build/esm/ ./build/esm-debug/ 7 | 8 | sed -i '/debug(/d' ./build/esm/*.js 9 | -------------------------------------------------------------------------------- /packages/socket.io-parser/support/package.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "commonjs" 3 | } 4 | -------------------------------------------------------------------------------- /packages/socket.io-parser/support/package.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /packages/socket.io-parser/test/support/env.js: -------------------------------------------------------------------------------- 1 | // WARNING this is bad practice 2 | // we only do this in our tests because we need to test engine.io-client 3 | // support in browsers and in node.js 4 | // some tests do not yet work in both 5 | module.exports.browser = typeof window !== "undefined"; 6 | -------------------------------------------------------------------------------- /packages/socket.io-parser/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/esm/", 4 | "target": "es2018", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "declaration": true 8 | }, 9 | "include": [ 10 | "./lib/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/socket.io-parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/cjs/", 4 | "target": "es2018", // Node.js 10 (https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping) 5 | "module": "commonjs", 6 | "declaration": true 7 | }, 8 | "include": [ 9 | "./lib/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/socket.io/test/fixtures/big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/packages/socket.io/test/fixtures/big.jpg -------------------------------------------------------------------------------- /packages/socket.io/test/fixtures/server-close.ts: -------------------------------------------------------------------------------- 1 | const server = require("http").createServer(); 2 | const ioc = require("socket.io-client"); 3 | const io = require("../..")(server); 4 | 5 | const srv = server.listen(() => { 6 | const socket = ioc.connect("ws://localhost:" + server.address().port); 7 | socket.on("connect", () => { 8 | io.close(); 9 | socket.close(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/socket.io/test/index.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | describe("socket.io", () => { 4 | require("./server-attachment"); 5 | require("./handshake"); 6 | require("./close"); 7 | require("./namespaces"); 8 | require("./socket"); 9 | require("./messaging-many"); 10 | require("./middleware"); 11 | require("./socket-middleware"); 12 | require("./v2-compatibility"); 13 | require("./socket-timeout"); 14 | require("./uws"); 15 | require("./utility-methods"); 16 | require("./connection-state-recovery"); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/socket.io/test/support/doge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/socketio/socket.io/e95f6abf93766662cd3b341599ed312f4330213f/packages/socket.io/test/support/doge.jpg -------------------------------------------------------------------------------- /packages/socket.io/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "target": "es2017", 5 | "module": "commonjs", 6 | "declaration": true, 7 | "esModuleInterop": true, 8 | 9 | "incremental": true, 10 | "skipLibCheck": true, 11 | 12 | "strict": true, 13 | "noImplicitAny": false, 14 | "noImplicitThis": false, 15 | "strictPropertyInitialization": false, 16 | "noImplicitReturns": true, 17 | }, 18 | "include": [ 19 | "./lib/**/*" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/socket.io/wrapper.mjs: -------------------------------------------------------------------------------- 1 | import io from "./dist/index.js"; 2 | 3 | export const {Server, Namespace, Socket} = io; 4 | --------------------------------------------------------------------------------