├── .gitignore ├── README.md ├── assets └── example.gif ├── load-test ├── advanced-test.yaml ├── custom.js └── simple-test.yaml ├── package-lock.json ├── package.json ├── public ├── index.html ├── main.js └── style.css └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## socketio-loadtesting 🚀 2 | 3 | This repository contains the tutorial files which companion my blog post on how to loadtest socket.io WebSocket applications. A live version of this application can be previewed at https://socketio-loadtest.herokuapp.com, and artillery.io loadtesting configuration files are found in the `load-test` directory. Usage instructions are in my blog post, [https://medium.com/@kyle_martin/load-testing-socket-io-web-applications-and-infrastructure-3e96011898e0](https://medium.com/@kyle_martin/load-testing-socket-io-web-applications-and-infrastructure-3e96011898e0) 4 | 5 | To run the application: 6 | 7 | ``` 8 | $ npm install 9 | $ npm start 10 | ``` 11 | 12 | The example socket.io application will be available on the configured `PORT`, otherwise it will default to port `8080`. 13 | 14 |  15 | 16 | -------------------------------------------------------------------------------- /assets/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/js-kyle/socketio-loadtesting/c2ea883ea150a51be39f58a99251e2343144d679/assets/example.gif -------------------------------------------------------------------------------- /load-test/advanced-test.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | target: "ws://localhost:8080" 3 | ensure: 4 | max: 500 # fail if max response time exceeds 500ms 5 | maxErrorRate: 1 # fail if error rate exceeds 1% 6 | socketio: 7 | transports: ["websocket"] 8 | processor: "./custom.js" # set a custom processor to load dynamic scenario data 9 | phases: 10 | - duration: 120 11 | arrivalRate: 10 12 | rampTo: 50 13 | name: "Warm up the application" 14 | - duration: 600 15 | arrivalRate: 50 16 | name: "Sustained max load" 17 | scenarios: 18 | - engine: "socketio" 19 | flow: 20 | - function: "getChatData" # load variables 21 | - emit: 22 | channel: "add user" 23 | data: "{{ name }}" 24 | - emit: 25 | channel: "new message" 26 | data: "{{ greeting }}" 27 | - think: 10 # stay connected for 10 seconds 28 | - emit: 29 | channel: "new message" 30 | data: "{{ goodbye }}" 31 | -------------------------------------------------------------------------------- /load-test/custom.js: -------------------------------------------------------------------------------- 1 | const {faker} = require('@faker-js/faker'); 2 | 3 | module.exports.getChatData = (userContext, events, done) => { 4 | userContext.vars.name = faker.name.findName(); 5 | userContext.vars.greeting = `Hello! I'm from ${faker.address.city()}`; 6 | userContext.vars.goodbye = `Goodbye, I will be back on ${faker.date.weekday()}`; 7 | done(); 8 | }; 9 | -------------------------------------------------------------------------------- /load-test/simple-test.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | target: "wss://socketio-loadtest.herokuapp.com" 3 | socketio: 4 | transports: ["websocket"] 5 | phases: 6 | - duration: 10 # Run scenario for 10 seconds 7 | arrivalCount: 20 # Create 20 virtual users per scenario 8 | scenarios: 9 | - engine: "socketio" 10 | flow: 11 | - emit: 12 | channel: "add user" 13 | data: "John Doe" 14 | - emit: 15 | channel: "new message" 16 | data: "Hello! {{ $randomString() }}" 17 | - think: 5 # do nothing for 5 seconds, then disconnect -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-loadtesting", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "express": { 8 | "version": "4.13.4", 9 | "resolved": "https://registry.npmjs.org/express/-/express-4.13.4.tgz", 10 | "integrity": "sha1-PAt288d1kMg0VzkGHsC9O6Bn7CQ=", 11 | "requires": { 12 | "accepts": "~1.2.12", 13 | "array-flatten": "1.1.1", 14 | "content-disposition": "0.5.1", 15 | "content-type": "~1.0.1", 16 | "cookie": "0.1.5", 17 | "cookie-signature": "1.0.6", 18 | "debug": "~2.2.0", 19 | "depd": "~1.1.0", 20 | "escape-html": "~1.0.3", 21 | "etag": "~1.7.0", 22 | "finalhandler": "0.4.1", 23 | "fresh": "0.3.0", 24 | "merge-descriptors": "1.0.1", 25 | "methods": "~1.1.2", 26 | "on-finished": "~2.3.0", 27 | "parseurl": "~1.3.1", 28 | "path-to-regexp": "0.1.7", 29 | "proxy-addr": "~1.0.10", 30 | "qs": "4.0.0", 31 | "range-parser": "~1.0.3", 32 | "send": "0.13.1", 33 | "serve-static": "~1.10.2", 34 | "type-is": "~1.6.6", 35 | "utils-merge": "1.0.0", 36 | "vary": "~1.0.1" 37 | }, 38 | "dependencies": { 39 | "accepts": { 40 | "version": "1.2.13", 41 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz", 42 | "integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=", 43 | "requires": { 44 | "mime-types": "~2.1.6", 45 | "negotiator": "0.5.3" 46 | }, 47 | "dependencies": { 48 | "mime-types": { 49 | "version": "2.1.24", 50 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 51 | "integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=", 52 | "requires": { 53 | "mime-db": "1.40.0" 54 | }, 55 | "dependencies": { 56 | "mime-db": { 57 | "version": "1.40.0", 58 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 59 | "integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI=" 60 | } 61 | } 62 | }, 63 | "negotiator": { 64 | "version": "0.5.3", 65 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz", 66 | "integrity": "sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g=" 67 | } 68 | } 69 | }, 70 | "array-flatten": { 71 | "version": "1.1.1", 72 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 73 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 74 | }, 75 | "content-disposition": { 76 | "version": "0.5.1", 77 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.1.tgz", 78 | "integrity": "sha1-h0dsamfI2qh+Muh2Ft+IO6f7Bxs=" 79 | }, 80 | "content-type": { 81 | "version": "1.0.4", 82 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 83 | "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" 84 | }, 85 | "cookie": { 86 | "version": "0.1.5", 87 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.5.tgz", 88 | "integrity": "sha1-armUiksa4hlSzSWIUwpHItQETXw=" 89 | }, 90 | "cookie-signature": { 91 | "version": "1.0.6", 92 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 93 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 94 | }, 95 | "debug": { 96 | "version": "2.2.0", 97 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", 98 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", 99 | "requires": { 100 | "ms": "0.7.1" 101 | }, 102 | "dependencies": { 103 | "ms": { 104 | "version": "0.7.1", 105 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", 106 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" 107 | } 108 | } 109 | }, 110 | "depd": { 111 | "version": "1.1.2", 112 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 113 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 114 | }, 115 | "escape-html": { 116 | "version": "1.0.3", 117 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 118 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 119 | }, 120 | "etag": { 121 | "version": "1.7.0", 122 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", 123 | "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=" 124 | }, 125 | "finalhandler": { 126 | "version": "0.4.1", 127 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.1.tgz", 128 | "integrity": "sha1-haF8bFmpRxfSYtYSMNSw6+PUoU0=", 129 | "requires": { 130 | "debug": "~2.2.0", 131 | "escape-html": "~1.0.3", 132 | "on-finished": "~2.3.0", 133 | "unpipe": "~1.0.0" 134 | }, 135 | "dependencies": { 136 | "unpipe": { 137 | "version": "1.0.0", 138 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 139 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 140 | } 141 | } 142 | }, 143 | "fresh": { 144 | "version": "0.3.0", 145 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", 146 | "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=" 147 | }, 148 | "merge-descriptors": { 149 | "version": "1.0.1", 150 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 151 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 152 | }, 153 | "methods": { 154 | "version": "1.1.2", 155 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 156 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 157 | }, 158 | "on-finished": { 159 | "version": "2.3.0", 160 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 161 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 162 | "requires": { 163 | "ee-first": "1.1.1" 164 | }, 165 | "dependencies": { 166 | "ee-first": { 167 | "version": "1.1.1", 168 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 169 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 170 | } 171 | } 172 | }, 173 | "parseurl": { 174 | "version": "1.3.3", 175 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 176 | "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=" 177 | }, 178 | "path-to-regexp": { 179 | "version": "0.1.7", 180 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 181 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 182 | }, 183 | "proxy-addr": { 184 | "version": "1.0.10", 185 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz", 186 | "integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=", 187 | "requires": { 188 | "forwarded": "~0.1.0", 189 | "ipaddr.js": "1.0.5" 190 | }, 191 | "dependencies": { 192 | "forwarded": { 193 | "version": "0.1.2", 194 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 195 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 196 | }, 197 | "ipaddr.js": { 198 | "version": "1.0.5", 199 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz", 200 | "integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c=" 201 | } 202 | } 203 | }, 204 | "qs": { 205 | "version": "4.0.0", 206 | "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz", 207 | "integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc=" 208 | }, 209 | "range-parser": { 210 | "version": "1.0.3", 211 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", 212 | "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU=" 213 | }, 214 | "send": { 215 | "version": "0.13.1", 216 | "resolved": "https://registry.npmjs.org/send/-/send-0.13.1.tgz", 217 | "integrity": "sha1-ow1fTILIqbrprQCh2bG9vm8Zntc=", 218 | "requires": { 219 | "debug": "~2.2.0", 220 | "depd": "~1.1.0", 221 | "destroy": "~1.0.4", 222 | "escape-html": "~1.0.3", 223 | "etag": "~1.7.0", 224 | "fresh": "0.3.0", 225 | "http-errors": "~1.3.1", 226 | "mime": "1.3.4", 227 | "ms": "0.7.1", 228 | "on-finished": "~2.3.0", 229 | "range-parser": "~1.0.3", 230 | "statuses": "~1.2.1" 231 | }, 232 | "dependencies": { 233 | "destroy": { 234 | "version": "1.0.4", 235 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 236 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 237 | }, 238 | "http-errors": { 239 | "version": "1.3.1", 240 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", 241 | "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", 242 | "requires": { 243 | "inherits": "~2.0.1", 244 | "statuses": "1" 245 | }, 246 | "dependencies": { 247 | "inherits": { 248 | "version": "2.0.4", 249 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 250 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" 251 | } 252 | } 253 | }, 254 | "mime": { 255 | "version": "1.3.4", 256 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", 257 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" 258 | }, 259 | "ms": { 260 | "version": "0.7.1", 261 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", 262 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" 263 | }, 264 | "statuses": { 265 | "version": "1.2.1", 266 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz", 267 | "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg=" 268 | } 269 | } 270 | }, 271 | "serve-static": { 272 | "version": "1.10.3", 273 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.3.tgz", 274 | "integrity": "sha1-zlpuzTEB/tXsCYJ9rCKpwpv7BTU=", 275 | "requires": { 276 | "escape-html": "~1.0.3", 277 | "parseurl": "~1.3.1", 278 | "send": "0.13.2" 279 | }, 280 | "dependencies": { 281 | "send": { 282 | "version": "0.13.2", 283 | "resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz", 284 | "integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=", 285 | "requires": { 286 | "debug": "~2.2.0", 287 | "depd": "~1.1.0", 288 | "destroy": "~1.0.4", 289 | "escape-html": "~1.0.3", 290 | "etag": "~1.7.0", 291 | "fresh": "0.3.0", 292 | "http-errors": "~1.3.1", 293 | "mime": "1.3.4", 294 | "ms": "0.7.1", 295 | "on-finished": "~2.3.0", 296 | "range-parser": "~1.0.3", 297 | "statuses": "~1.2.1" 298 | }, 299 | "dependencies": { 300 | "destroy": { 301 | "version": "1.0.4", 302 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 303 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 304 | }, 305 | "http-errors": { 306 | "version": "1.3.1", 307 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", 308 | "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", 309 | "requires": { 310 | "inherits": "~2.0.1", 311 | "statuses": "1" 312 | }, 313 | "dependencies": { 314 | "inherits": { 315 | "version": "2.0.4", 316 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 317 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" 318 | } 319 | } 320 | }, 321 | "mime": { 322 | "version": "1.3.4", 323 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", 324 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" 325 | }, 326 | "ms": { 327 | "version": "0.7.1", 328 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", 329 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" 330 | }, 331 | "statuses": { 332 | "version": "1.2.1", 333 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz", 334 | "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg=" 335 | } 336 | } 337 | } 338 | } 339 | }, 340 | "type-is": { 341 | "version": "1.6.18", 342 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 343 | "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=", 344 | "requires": { 345 | "media-typer": "0.3.0", 346 | "mime-types": "~2.1.24" 347 | }, 348 | "dependencies": { 349 | "media-typer": { 350 | "version": "0.3.0", 351 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 352 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 353 | }, 354 | "mime-types": { 355 | "version": "2.1.24", 356 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 357 | "integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=", 358 | "requires": { 359 | "mime-db": "1.40.0" 360 | }, 361 | "dependencies": { 362 | "mime-db": { 363 | "version": "1.40.0", 364 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 365 | "integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI=" 366 | } 367 | } 368 | } 369 | } 370 | }, 371 | "utils-merge": { 372 | "version": "1.0.0", 373 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", 374 | "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" 375 | }, 376 | "vary": { 377 | "version": "1.0.1", 378 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz", 379 | "integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA=" 380 | } 381 | } 382 | }, 383 | "faker": { 384 | "version": "4.1.0", 385 | "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", 386 | "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=", 387 | "dev": true 388 | }, 389 | "socket.io": { 390 | "version": "2.2.0", 391 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", 392 | "integrity": "sha1-8PYzFh72cSyXKzB1mOzQjJsbTVs=", 393 | "requires": { 394 | "debug": "~4.1.0", 395 | "engine.io": "~3.3.1", 396 | "has-binary2": "~1.0.2", 397 | "socket.io-adapter": "~1.1.0", 398 | "socket.io-client": "2.2.0", 399 | "socket.io-parser": "~3.3.0" 400 | }, 401 | "dependencies": { 402 | "debug": { 403 | "version": "4.1.1", 404 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 405 | "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", 406 | "requires": { 407 | "ms": "^2.1.1" 408 | }, 409 | "dependencies": { 410 | "ms": { 411 | "version": "2.1.2", 412 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 413 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" 414 | } 415 | } 416 | }, 417 | "engine.io": { 418 | "version": "3.3.2", 419 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", 420 | "integrity": "sha1-GMvItvNulGHFwPgd8rgw3hYFilk=", 421 | "requires": { 422 | "accepts": "~1.3.4", 423 | "base64id": "1.0.0", 424 | "cookie": "0.3.1", 425 | "debug": "~3.1.0", 426 | "engine.io-parser": "~2.1.0", 427 | "ws": "~6.1.0" 428 | }, 429 | "dependencies": { 430 | "accepts": { 431 | "version": "1.3.7", 432 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 433 | "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=", 434 | "requires": { 435 | "mime-types": "~2.1.24", 436 | "negotiator": "0.6.2" 437 | }, 438 | "dependencies": { 439 | "mime-types": { 440 | "version": "2.1.24", 441 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 442 | "integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=", 443 | "requires": { 444 | "mime-db": "1.40.0" 445 | }, 446 | "dependencies": { 447 | "mime-db": { 448 | "version": "1.40.0", 449 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 450 | "integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI=" 451 | } 452 | } 453 | }, 454 | "negotiator": { 455 | "version": "0.6.2", 456 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 457 | "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=" 458 | } 459 | } 460 | }, 461 | "base64id": { 462 | "version": "1.0.0", 463 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", 464 | "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" 465 | }, 466 | "cookie": { 467 | "version": "0.3.1", 468 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 469 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 470 | }, 471 | "debug": { 472 | "version": "3.1.0", 473 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 474 | "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", 475 | "requires": { 476 | "ms": "2.0.0" 477 | }, 478 | "dependencies": { 479 | "ms": { 480 | "version": "2.0.0", 481 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 482 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 483 | } 484 | } 485 | }, 486 | "engine.io-parser": { 487 | "version": "2.1.3", 488 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", 489 | "integrity": "sha1-dXq5cPvy37Mse3SwMyFtVznveaY=", 490 | "requires": { 491 | "after": "0.8.2", 492 | "arraybuffer.slice": "~0.0.7", 493 | "base64-arraybuffer": "0.1.5", 494 | "blob": "0.0.5", 495 | "has-binary2": "~1.0.2" 496 | }, 497 | "dependencies": { 498 | "after": { 499 | "version": "0.8.2", 500 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", 501 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" 502 | }, 503 | "arraybuffer.slice": { 504 | "version": "0.0.7", 505 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", 506 | "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=" 507 | }, 508 | "base64-arraybuffer": { 509 | "version": "0.1.5", 510 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", 511 | "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" 512 | }, 513 | "blob": { 514 | "version": "0.0.5", 515 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", 516 | "integrity": "sha1-1oDu7yX4zZGtUz9bAe7UjmTK9oM=" 517 | } 518 | } 519 | }, 520 | "ws": { 521 | "version": "6.1.4", 522 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", 523 | "integrity": "sha1-W1yIAK+rkl6UzLKdFTyNAsF3bvk=", 524 | "requires": { 525 | "async-limiter": "~1.0.0" 526 | }, 527 | "dependencies": { 528 | "async-limiter": { 529 | "version": "1.0.1", 530 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 531 | "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=" 532 | } 533 | } 534 | } 535 | } 536 | }, 537 | "has-binary2": { 538 | "version": "1.0.3", 539 | "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", 540 | "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", 541 | "requires": { 542 | "isarray": "2.0.1" 543 | }, 544 | "dependencies": { 545 | "isarray": { 546 | "version": "2.0.1", 547 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", 548 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" 549 | } 550 | } 551 | }, 552 | "socket.io-adapter": { 553 | "version": "1.1.1", 554 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", 555 | "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" 556 | }, 557 | "socket.io-client": { 558 | "version": "2.2.0", 559 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", 560 | "integrity": "sha1-hOc+48Q9UCDMwaJY+u65rsJyOvc=", 561 | "requires": { 562 | "backo2": "1.0.2", 563 | "base64-arraybuffer": "0.1.5", 564 | "component-bind": "1.0.0", 565 | "component-emitter": "1.2.1", 566 | "debug": "~3.1.0", 567 | "engine.io-client": "~3.3.1", 568 | "has-binary2": "~1.0.2", 569 | "has-cors": "1.1.0", 570 | "indexof": "0.0.1", 571 | "object-component": "0.0.3", 572 | "parseqs": "0.0.5", 573 | "parseuri": "0.0.5", 574 | "socket.io-parser": "~3.3.0", 575 | "to-array": "0.1.4" 576 | }, 577 | "dependencies": { 578 | "backo2": { 579 | "version": "1.0.2", 580 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", 581 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" 582 | }, 583 | "base64-arraybuffer": { 584 | "version": "0.1.5", 585 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", 586 | "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" 587 | }, 588 | "component-bind": { 589 | "version": "1.0.0", 590 | "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", 591 | "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" 592 | }, 593 | "component-emitter": { 594 | "version": "1.2.1", 595 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 596 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" 597 | }, 598 | "debug": { 599 | "version": "3.1.0", 600 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 601 | "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", 602 | "requires": { 603 | "ms": "2.0.0" 604 | }, 605 | "dependencies": { 606 | "ms": { 607 | "version": "2.0.0", 608 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 609 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 610 | } 611 | } 612 | }, 613 | "engine.io-client": { 614 | "version": "3.3.2", 615 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", 616 | "integrity": "sha1-BOBoeY11vtoUN1omS7PXQte8M6o=", 617 | "requires": { 618 | "component-emitter": "1.2.1", 619 | "component-inherit": "0.0.3", 620 | "debug": "~3.1.0", 621 | "engine.io-parser": "~2.1.1", 622 | "has-cors": "1.1.0", 623 | "indexof": "0.0.1", 624 | "parseqs": "0.0.5", 625 | "parseuri": "0.0.5", 626 | "ws": "~6.1.0", 627 | "xmlhttprequest-ssl": "~1.5.4", 628 | "yeast": "0.1.2" 629 | }, 630 | "dependencies": { 631 | "component-inherit": { 632 | "version": "0.0.3", 633 | "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", 634 | "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" 635 | }, 636 | "engine.io-parser": { 637 | "version": "2.1.3", 638 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", 639 | "integrity": "sha1-dXq5cPvy37Mse3SwMyFtVznveaY=", 640 | "requires": { 641 | "after": "0.8.2", 642 | "arraybuffer.slice": "~0.0.7", 643 | "base64-arraybuffer": "0.1.5", 644 | "blob": "0.0.5", 645 | "has-binary2": "~1.0.2" 646 | }, 647 | "dependencies": { 648 | "after": { 649 | "version": "0.8.2", 650 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", 651 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" 652 | }, 653 | "arraybuffer.slice": { 654 | "version": "0.0.7", 655 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", 656 | "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=" 657 | }, 658 | "blob": { 659 | "version": "0.0.5", 660 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", 661 | "integrity": "sha1-1oDu7yX4zZGtUz9bAe7UjmTK9oM=" 662 | } 663 | } 664 | }, 665 | "ws": { 666 | "version": "6.1.4", 667 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", 668 | "integrity": "sha1-W1yIAK+rkl6UzLKdFTyNAsF3bvk=", 669 | "requires": { 670 | "async-limiter": "~1.0.0" 671 | }, 672 | "dependencies": { 673 | "async-limiter": { 674 | "version": "1.0.1", 675 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 676 | "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=" 677 | } 678 | } 679 | }, 680 | "xmlhttprequest-ssl": { 681 | "version": "1.5.5", 682 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", 683 | "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" 684 | }, 685 | "yeast": { 686 | "version": "0.1.2", 687 | "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", 688 | "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" 689 | } 690 | } 691 | }, 692 | "has-cors": { 693 | "version": "1.1.0", 694 | "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", 695 | "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" 696 | }, 697 | "indexof": { 698 | "version": "0.0.1", 699 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", 700 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" 701 | }, 702 | "object-component": { 703 | "version": "0.0.3", 704 | "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", 705 | "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" 706 | }, 707 | "parseqs": { 708 | "version": "0.0.5", 709 | "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", 710 | "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", 711 | "requires": { 712 | "better-assert": "~1.0.0" 713 | }, 714 | "dependencies": { 715 | "better-assert": { 716 | "version": "1.0.2", 717 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", 718 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", 719 | "requires": { 720 | "callsite": "1.0.0" 721 | }, 722 | "dependencies": { 723 | "callsite": { 724 | "version": "1.0.0", 725 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", 726 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" 727 | } 728 | } 729 | } 730 | } 731 | }, 732 | "parseuri": { 733 | "version": "0.0.5", 734 | "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", 735 | "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", 736 | "requires": { 737 | "better-assert": "~1.0.0" 738 | }, 739 | "dependencies": { 740 | "better-assert": { 741 | "version": "1.0.2", 742 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", 743 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", 744 | "requires": { 745 | "callsite": "1.0.0" 746 | }, 747 | "dependencies": { 748 | "callsite": { 749 | "version": "1.0.0", 750 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", 751 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" 752 | } 753 | } 754 | } 755 | } 756 | }, 757 | "to-array": { 758 | "version": "0.1.4", 759 | "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", 760 | "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" 761 | } 762 | } 763 | }, 764 | "socket.io-parser": { 765 | "version": "3.3.0", 766 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", 767 | "integrity": "sha1-K1KpalCf3zFEC6QP7WCUx9TxJi8=", 768 | "requires": { 769 | "component-emitter": "1.2.1", 770 | "debug": "~3.1.0", 771 | "isarray": "2.0.1" 772 | }, 773 | "dependencies": { 774 | "component-emitter": { 775 | "version": "1.2.1", 776 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 777 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" 778 | }, 779 | "debug": { 780 | "version": "3.1.0", 781 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 782 | "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", 783 | "requires": { 784 | "ms": "2.0.0" 785 | }, 786 | "dependencies": { 787 | "ms": { 788 | "version": "2.0.0", 789 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 790 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 791 | } 792 | } 793 | }, 794 | "isarray": { 795 | "version": "2.0.1", 796 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", 797 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" 798 | } 799 | } 800 | } 801 | } 802 | } 803 | } 804 | } 805 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket.io-loadtesting", 3 | "version": "1.0.0", 4 | "description": "socket.io loadtesting examples", 5 | "main": "server.js", 6 | "author": "Kyle Martin", 7 | "license": "MIT", 8 | "dependencies": { 9 | "@faker-js/faker": "^6.2.0", 10 | "express": "4.17.3", 11 | "socket.io": "^4.5.0" 12 | }, 13 | "scripts": { 14 | "start": "node server.js" 15 | }, 16 | "devDependencies": { 17 | "faker": "^6.6.6" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |