@venizia/ignis-docs 0.2.1-0 → 0.2.1-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/best-practices/architectural-patterns.md +3 -3
- package/content/best-practices/code-style-standards/naming-conventions.md +1 -1
- package/content/best-practices/contribution-workflow.md +2 -2
- package/content/best-practices/error-handling.md +94 -89
- package/content/best-practices/security-guidelines.md +5 -5
- package/content/extensions/components/api-reference.md +22 -21
- package/content/extensions/components/authentication/api.md +64 -28
- package/content/extensions/components/authentication/errors.md +19 -5
- package/content/extensions/components/authentication/index.md +19 -18
- package/content/extensions/components/authentication/usage.md +55 -30
- package/content/extensions/components/authorization/api.md +351 -84
- package/content/extensions/components/authorization/errors.md +51 -17
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +24 -16
- package/content/extensions/components/authorization/usage.md +45 -21
- package/content/extensions/components/health-check.md +15 -9
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +105 -54
- package/content/extensions/components/mail/errors.md +12 -10
- package/content/extensions/components/mail/index.md +32 -13
- package/content/extensions/components/mail/usage.md +26 -18
- package/content/extensions/components/request-tracker.md +18 -14
- package/content/extensions/components/socket-io/api.md +377 -882
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +72 -88
- package/content/extensions/components/socket-io/usage.md +107 -117
- package/content/extensions/components/static-asset/api.md +83 -31
- package/content/extensions/components/static-asset/errors.md +18 -7
- package/content/extensions/components/static-asset/index.md +18 -11
- package/content/extensions/components/static-asset/usage.md +11 -6
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +58 -27
- package/content/extensions/components/websocket/errors.md +3 -3
- package/content/extensions/components/websocket/index.md +8 -7
- package/content/extensions/components/websocket/usage.md +21 -8
- package/content/extensions/helpers/cron/index.md +8 -7
- package/content/extensions/helpers/crypto/index.md +16 -8
- package/content/extensions/helpers/crypto/reference.md +96 -24
- package/content/extensions/helpers/env/index.md +14 -10
- package/content/extensions/helpers/error/index.md +99 -23
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +23 -6
- package/content/extensions/helpers/inversion/reference.md +30 -22
- package/content/extensions/helpers/kafka/admin.md +3 -2
- package/content/extensions/helpers/kafka/compile-binary.md +69 -44
- package/content/extensions/helpers/kafka/consumer.md +24 -21
- package/content/extensions/helpers/kafka/examples.md +22 -234
- package/content/extensions/helpers/kafka/index.md +30 -62
- package/content/extensions/helpers/kafka/producer.md +31 -26
- package/content/extensions/helpers/kafka/schema-registry.md +19 -14
- package/content/extensions/helpers/logger/hf-logger.md +49 -22
- package/content/extensions/helpers/logger/index.md +37 -12
- package/content/extensions/helpers/logger/pino.md +31 -11
- package/content/extensions/helpers/logger/reference.md +243 -52
- package/content/extensions/helpers/network/api.md +65 -30
- package/content/extensions/helpers/network/index.md +32 -11
- package/content/extensions/helpers/queue/index.md +17 -6
- package/content/extensions/helpers/queue/reference.md +52 -25
- package/content/extensions/helpers/redis/index.md +29 -11
- package/content/extensions/helpers/redis/reference.md +85 -28
- package/content/extensions/helpers/secrets/index.md +82 -12
- package/content/extensions/helpers/socket-io/api.md +40 -21
- package/content/extensions/helpers/socket-io/index.md +26 -10
- package/content/extensions/helpers/storage/api.md +42 -24
- package/content/extensions/helpers/storage/index.md +10 -7
- package/content/extensions/helpers/types/index.md +20 -7
- package/content/extensions/helpers/types/reference.md +53 -14
- package/content/extensions/helpers/uid/index.md +166 -10
- package/content/extensions/helpers/websocket/api.md +52 -13
- package/content/extensions/helpers/websocket/index.md +7 -4
- package/content/extensions/helpers/worker-thread/index.md +9 -5
- package/content/extensions/helpers/worker-thread/reference.md +20 -20
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +26 -14
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +4 -3
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +7 -6
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +63 -21
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +14 -14
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +32 -31
- package/content/references/base/datasources.md +6 -6
- package/content/references/base/dependency-injection.md +12 -11
- package/content/references/base/filter-system/application-usage.md +54 -30
- package/content/references/base/filter-system/array-operators.md +24 -46
- package/content/references/base/filter-system/comparison-operators.md +47 -67
- package/content/references/base/filter-system/default-filter.md +59 -53
- package/content/references/base/filter-system/fields-order-pagination.md +92 -146
- package/content/references/base/filter-system/index.md +25 -13
- package/content/references/base/filter-system/json-filtering.md +45 -184
- package/content/references/base/filter-system/list-operators.md +23 -53
- package/content/references/base/filter-system/logical-operators.md +63 -121
- package/content/references/base/filter-system/null-operators.md +34 -104
- package/content/references/base/filter-system/pattern-matching.md +40 -55
- package/content/references/base/filter-system/quick-reference.md +86 -198
- package/content/references/base/filter-system/range-operators.md +18 -46
- package/content/references/base/filter-system/tips.md +6 -6
- package/content/references/base/filter-system/use-cases.md +33 -15
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +11 -10
- package/content/references/base/models-reference.md +17 -17
- package/content/references/base/models.md +4 -3
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +224 -326
- package/content/references/base/repositories/index.md +19 -6
- package/content/references/base/repositories/mixins.md +5 -5
- package/content/references/base/repositories/relations.md +160 -293
- package/content/references/base/repositories/soft-deletable.md +16 -6
- package/content/references/base/secrets.md +17 -13
- package/content/references/base/services.md +6 -4
- package/content/references/configuration/environment-variables.md +31 -23
- package/content/references/configuration/index.md +6 -4
- package/content/references/index.md +1 -1
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +5 -1
- package/content/references/utilities/jsx-reference.md +11 -11
- package/content/references/utilities/jsx.md +2 -2
- package/content/references/utilities/module.md +78 -25
- package/content/references/utilities/request.md +2 -1
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +2 -2
- package/content/references/utilities/statuses-reference.md +4 -4
- package/content/references/utilities/statuses.md +5 -5
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +17 -16
|
@@ -1,46 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Socket.IO Component - Error Reference
|
|
3
|
+
description: Error conditions, failure messages, and troubleshooting for the Socket.IO component, server helper, and client helper
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
# Error Reference
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
Every error condition the Socket.IO component and its two helpers can raise, plus fixes for the ones you'll actually hit.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
## Error conditions
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
### Component errors
|
|
14
|
+
|
|
15
|
+
| Method | Condition | Error message |
|
|
16
|
+
|---|---|---|
|
|
11
17
|
| `binding()` | `application` is falsy | `"[binding] Invalid application to bind SocketIOComponent"` |
|
|
12
18
|
| `binding()` | Unsupported runtime | `"[SocketIOComponent] Unsupported runtime: <runtime>"` |
|
|
13
|
-
| `resolveBindings()` | `REDIS_CONNECTION`
|
|
19
|
+
| `resolveBindings()` | `REDIS_CONNECTION` fails `isRedisHelper()` | `"Invalid instance of redisConnection..."` |
|
|
14
20
|
| `resolveBindings()` | `AUTHENTICATE_HANDLER` is falsy | `"[DANGER][SocketIOComponent] Invalid authenticateFn to setup io socket server!"` |
|
|
15
21
|
| `registerNodeHook()` | HTTP server not available | `"[SocketIOComponent] HTTP server not available for Node.js runtime!"` |
|
|
16
22
|
|
|
17
|
-
### Server
|
|
23
|
+
### Server helper errors
|
|
18
24
|
|
|
19
|
-
| Method | Condition | Error
|
|
20
|
-
|
|
25
|
+
| Method | Condition | Error message |
|
|
26
|
+
|---|---|---|
|
|
21
27
|
| `setRuntime()` | Node.js runtime, `server` missing | `"[SocketIOServerHelper] Invalid HTTP server for Node.js runtime!"` |
|
|
22
28
|
| `setRuntime()` | Bun runtime, `engine` missing | `"[SocketIOServerHelper] Invalid @socket.io/bun-engine instance for Bun runtime!"` |
|
|
23
29
|
| `setRuntime()` | Unknown runtime | `"[SocketIOServerHelper] Unsupported runtime!"` |
|
|
24
30
|
| `initRedisClients()` | `redisConnection` is falsy | `"Invalid redis connection to config socket.io adapter!"` |
|
|
25
|
-
| `initIOServer()` | Node.js
|
|
26
|
-
| `initIOServer()` | Bun
|
|
31
|
+
| `initIOServer()` | Node.js, `server` missing at configure time | `"[DANGER] Invalid HTTP server instance to init Socket.io server!"` |
|
|
32
|
+
| `initIOServer()` | Bun, `engine` missing at configure time | `"[DANGER] Invalid @socket.io/bun-engine instance to init Socket.io server!"` |
|
|
27
33
|
| `initIOServer()` | Unknown runtime at configure time | `"[configure] Unsupported runtime: <runtime>"` |
|
|
28
34
|
| `getEngine()` | Runtime is not Bun | `"[getEngine] Engine is only available for Bun runtime!"` |
|
|
29
35
|
| `on()` | `topic` is empty | `"[on] Invalid topic to start binding handler"` |
|
|
30
|
-
| `on()` | `handler` is falsy | `"[on] Invalid event handler
|
|
36
|
+
| `on()` | `handler` is falsy | `"[on] Invalid event handler \| topic: <topic>"` |
|
|
31
37
|
| `on()` | IO server not initialized | `"[on] IOServer is not initialized yet!"` |
|
|
32
38
|
|
|
33
|
-
### Client
|
|
39
|
+
### Client helper errors
|
|
34
40
|
|
|
35
|
-
| Method | Condition | Error
|
|
36
|
-
|
|
37
|
-
| `emit()` | Socket not connected | `"Invalid socket client state to emit"`
|
|
38
|
-
| `emit()` | `topic` is falsy | `"Topic is required to emit"`
|
|
41
|
+
| Method | Condition | statusCode | Error message |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| `emit()` | Socket not connected | `400` | `"Invalid socket client state to emit"` |
|
|
44
|
+
| `emit()` | `topic` is falsy | `400` | `"Topic is required to emit"` |
|
|
39
45
|
|
|
40
|
-
### Server
|
|
46
|
+
### Server authentication errors (sent to the client)
|
|
41
47
|
|
|
42
48
|
| Condition | Event | Message |
|
|
43
|
-
|
|
49
|
+
|---|---|---|
|
|
44
50
|
| `authenticateFn` returned `false` | `unauthenticated` | `"Invalid token to authenticate! Please login again!"` |
|
|
45
51
|
| `authenticateFn` threw an error | `unauthenticated` | `"Failed to authenticate connection! Please login again!"` |
|
|
46
52
|
|
|
@@ -48,74 +54,66 @@
|
|
|
48
54
|
|
|
49
55
|
### "SocketIO not initialized"
|
|
50
56
|
|
|
51
|
-
**Cause
|
|
52
|
-
|
|
53
|
-
**Fix**: Use the lazy getter pattern shown in the [Usage & Examples](./usage) page. Never `@inject` `SOCKET_IO_INSTANCE` directly in a constructor -- it doesn't exist yet at construction time.
|
|
57
|
+
- **Cause:** You used `SocketIOServerHelper` before the server started - typically during DI construction.
|
|
58
|
+
- **Fix:** Use the lazy getter pattern from [Usage & Examples](./usage#inject-the-helper-in-a-service-or-controller). Never `@inject` `SOCKET_IO_INSTANCE` in a constructor - it doesn't exist yet at that point.
|
|
54
59
|
|
|
55
60
|
### "Invalid instance of redisConnection"
|
|
56
61
|
|
|
57
|
-
**Cause
|
|
58
|
-
|
|
59
|
-
**Fix**: Use one of the concrete topology helpers:
|
|
62
|
+
- **Cause:** The value bound to `REDIS_CONNECTION` isn't an `AbstractRedisHelper` instance - not a `RedisSingleHelper`, `RedisClusterHelper`, or `RedisSentinelHelper`.
|
|
63
|
+
- **Fix:** Bind one of the concrete topology helpers, never a raw `ioredis` client.
|
|
60
64
|
|
|
61
65
|
```typescript
|
|
62
66
|
import { SocketIOBindingKeys } from '@venizia/ignis/socket-io';
|
|
63
67
|
|
|
64
|
-
// Correct
|
|
68
|
+
// Correct - single instance
|
|
65
69
|
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION })
|
|
66
70
|
.toValue(new RedisSingleHelper({ name: 'socket-io', host, port, password }));
|
|
67
71
|
|
|
68
|
-
// Correct
|
|
72
|
+
// Correct - cluster mode
|
|
69
73
|
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION })
|
|
70
74
|
.toValue(new RedisClusterHelper({ name: 'socket-io', nodes, password }));
|
|
71
75
|
|
|
72
|
-
// Wrong
|
|
73
|
-
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION })
|
|
74
|
-
.toValue(new Redis(6379)); // This is NOT an AbstractRedisHelper!
|
|
76
|
+
// Wrong - raw ioredis client, not an AbstractRedisHelper
|
|
77
|
+
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION }).toValue(new Redis(6379));
|
|
75
78
|
```
|
|
76
79
|
|
|
77
80
|
### "Cannot find module '@socket.io/bun-engine'"
|
|
78
81
|
|
|
79
|
-
**Cause
|
|
80
|
-
|
|
81
|
-
**Fix**: `bun add @socket.io/bun-engine`
|
|
82
|
+
- **Cause:** Running on Bun without the optional peer dependency installed.
|
|
83
|
+
- **Fix:** `bun add @socket.io/bun-engine`
|
|
82
84
|
|
|
83
85
|
### Socket.IO connects but events aren't received
|
|
84
86
|
|
|
85
|
-
**Cause
|
|
86
|
-
|
|
87
|
-
**Fix**: Ensure your client emits the authenticate event:
|
|
87
|
+
- **Cause:** The client never emitted `authenticate`. Unauthenticated clients are disconnected after the timeout (default: 10 seconds).
|
|
88
|
+
- **Fix:** Emit `authenticate` right after connecting.
|
|
88
89
|
|
|
89
90
|
```typescript
|
|
90
91
|
socket.on('connect', () => {
|
|
91
92
|
socket.emit('authenticate');
|
|
92
93
|
});
|
|
93
94
|
|
|
94
|
-
socket.on('authenticated',
|
|
95
|
+
socket.on('authenticated', data => {
|
|
95
96
|
// Now ready to send/receive events
|
|
96
97
|
});
|
|
97
98
|
```
|
|
98
99
|
|
|
99
100
|
### "Invalid socket client state to emit"
|
|
100
101
|
|
|
101
|
-
**Cause
|
|
102
|
-
|
|
103
|
-
**Fix**: Ensure the socket is connected before emitting. Check `client.getSocketClient().connected` or wait for the `onConnected` callback.
|
|
102
|
+
- **Cause:** You called `emit()` on `SocketIOClientHelper` while the socket wasn't connected.
|
|
103
|
+
- **Fix:** Confirm the socket is connected before emitting. Check `client.getSocketClient().connected`, or wait for the `onConnected` callback.
|
|
104
104
|
|
|
105
105
|
### Client disconnects immediately after connecting
|
|
106
106
|
|
|
107
|
-
**Cause
|
|
108
|
-
|
|
109
|
-
**Fix**: Emit `authenticate` immediately on connect, or increase the `authenticateTimeout` in the server helper options.
|
|
107
|
+
- **Cause:** The authentication timeout expired (default: 10 seconds) before the client emitted `authenticate`.
|
|
108
|
+
- **Fix:** Emit `authenticate` immediately on connect, or raise `authenticateTimeout` in the server helper options.
|
|
110
109
|
|
|
111
110
|
### Room join requests are silently rejected
|
|
112
111
|
|
|
113
|
-
**Cause
|
|
114
|
-
|
|
115
|
-
**Fix**: Bind a `VALIDATE_ROOM_HANDLER` that returns the list of allowed rooms.
|
|
112
|
+
- **Cause:** No `validateRoomFn` is bound. Every join is rejected by design when it's missing - security-by-default.
|
|
113
|
+
- **Fix:** Bind a `VALIDATE_ROOM_HANDLER` that returns the list of allowed rooms.
|
|
116
114
|
|
|
117
|
-
## See
|
|
115
|
+
## See also
|
|
118
116
|
|
|
119
|
-
- [
|
|
120
|
-
- [Usage & Examples](./usage)
|
|
121
|
-
- [
|
|
117
|
+
- [Overview](./) - quick start, imports, common configuration tasks
|
|
118
|
+
- [Usage & Examples](./usage) - full setup steps, server-side usage, client helper, advanced patterns
|
|
119
|
+
- [Full Reference](./api) - architecture, configuration reference, method signatures, internals, types
|
|
@@ -1,47 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Socket.IO Component
|
|
3
|
+
description: Wires SocketIOServerHelper into the app lifecycle for Node.js and Bun, with Redis-backed horizontal scaling and a mandatory authentication handshake
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
# Socket.IO Component
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
`SocketIOComponent` registers a [`SocketIOServerHelper`](/extensions/helpers/socket-io/) on your application once the server starts. It runs on both Node.js and Bun, and scales across instances through a Redis adapter. Every client must authenticate before it can send or receive anything.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
| **Package** | `@venizia/ignis` (core) |
|
|
10
|
-
| **Class** | `SocketIOComponent` |
|
|
11
|
-
| **Server Helper** | [`SocketIOServerHelper`](/extensions/helpers/socket-io/) |
|
|
12
|
-
| **Client Helper** | [`SocketIOClientHelper`](/extensions/helpers/socket-io/) |
|
|
13
|
-
| **Runtimes** | Node.js (`@hono/node-server`) and Bun (native) |
|
|
14
|
-
| **Scaling** | `@socket.io/redis-adapter` + `@socket.io/redis-emitter` |
|
|
11
|
+
> [!TIP]
|
|
12
|
+
> Bun-only and don't need Socket.IO's handshake protocol? The [WebSocket Component](../websocket/) is a lighter alternative.
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
> `SocketIOComponent` and `SocketIOBindingKeys` are **not** exported from the `@venizia/ignis` barrel -- import from the `@venizia/ignis/socket-io` subpath.
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
// From core -- subpath import (NOT from '@venizia/ignis')
|
|
21
|
-
import { SocketIOComponent, SocketIOBindingKeys } from '@venizia/ignis/socket-io';
|
|
22
|
-
|
|
23
|
-
// From helpers -- subpath import
|
|
24
|
-
import { SocketIOServerHelper, SocketIOClientHelper, SocketIOConstants } from '@venizia/ignis-helpers/socket-io';
|
|
25
|
-
import type { TSocketIOAuthenticateFn, TSocketIOValidateRoomFn } from '@venizia/ignis-helpers/socket-io';
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
**Use cases:**
|
|
29
|
-
|
|
30
|
-
- Live notifications and alerts
|
|
31
|
-
- Real-time chat and collaborative editing
|
|
32
|
-
- Live dashboards and monitoring streams
|
|
33
|
-
- Multiplayer game state synchronization
|
|
34
|
-
- Service-to-service real-time messaging (via `SocketIOClientHelper`)
|
|
35
|
-
|
|
36
|
-
## Setup
|
|
37
|
-
|
|
38
|
-
Three pieces are bound in `preConfigure()`, before the component itself is registered:
|
|
39
|
-
|
|
40
|
-
| Step | Binding key | Required |
|
|
41
|
-
|------|-------------|----------|
|
|
42
|
-
| 1. Redis connection | `SocketIOBindingKeys.REDIS_CONNECTION` | Yes |
|
|
43
|
-
| 2. Authenticate handler | `SocketIOBindingKeys.AUTHENTICATE_HANDLER` | Yes |
|
|
44
|
-
| 3. Room / connected handlers | `VALIDATE_ROOM_HANDLER`, `CLIENT_CONNECTED_HANDLER` | No |
|
|
14
|
+
## In one example
|
|
45
15
|
|
|
46
16
|
```typescript
|
|
47
17
|
import { BaseApplication } from '@venizia/ignis';
|
|
@@ -51,39 +21,43 @@ import type { TSocketIOAuthenticateFn } from '@venizia/ignis-helpers/socket-io';
|
|
|
51
21
|
|
|
52
22
|
export class Application extends BaseApplication {
|
|
53
23
|
preConfigure(): ValueOrPromise<void> {
|
|
54
|
-
// 1. Redis connection
|
|
55
|
-
|
|
56
|
-
name: 'socket-io-redis',
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
-
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION }).toValue(redisHelper);
|
|
62
|
-
|
|
63
|
-
// 2. Authentication handler -- required
|
|
24
|
+
// 1. Redis connection (required - used for the adapter + emitter)
|
|
25
|
+
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION }).toValue(
|
|
26
|
+
new RedisSingleHelper({ name: 'socket-io-redis', host: 'localhost', port: 6379, autoConnect: false }),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
// 2. Authenticate handler (required - decides accept/reject per client)
|
|
64
30
|
const authenticateFn: TSocketIOAuthenticateFn = handshake => !!handshake.headers.authorization;
|
|
65
31
|
this.bind({ key: SocketIOBindingKeys.AUTHENTICATE_HANDLER }).toValue(authenticateFn);
|
|
66
32
|
|
|
67
|
-
// 3. Register the
|
|
33
|
+
// 3. Register - binding() validates the two bindings above and defers the rest
|
|
68
34
|
this.component(SocketIOComponent);
|
|
69
35
|
}
|
|
70
36
|
}
|
|
71
37
|
```
|
|
72
38
|
|
|
39
|
+
`SocketIOComponent` and `SocketIOBindingKeys` come from the `@venizia/ignis/socket-io` subpath. They are **not** exported from the `@venizia/ignis` root barrel. Helper types (`TSocketIOAuthenticateFn`, `SocketIOServerHelper`, `SocketIOClientHelper`, `SocketIOConstants`, ...) come from `@venizia/ignis-helpers/socket-io`.
|
|
40
|
+
|
|
73
41
|
> [!WARNING]
|
|
74
|
-
> `autoConnect: false` is required on the Redis helper
|
|
42
|
+
> `autoConnect: false` is required on the Redis helper. The server helper duplicates the connection into 3 independent clients and connects them itself during `configure()`. Connect the parent first and it races against the duplicates. Full explanation in [Usage & Examples](./usage#full-setup).
|
|
75
43
|
|
|
76
|
-
## How
|
|
44
|
+
## How it works
|
|
77
45
|
|
|
78
|
-
|
|
79
|
-
- **Runtime detection picks the wiring.** `RuntimeModules.detect()` selects Node.js (Socket.IO attaches to `node:http.Server` directly) or Bun (`@socket.io/bun-engine` is dynamically imported and wired into `server.reload()`). See the [runtime matrix](./api#runtime-specific-behavior) for the full comparison.
|
|
80
|
-
- **One Redis connection becomes three.** The connection you bind is never consumed directly -- the helper calls `duplicateClient()` three times: a pub/sub pair for the Redis adapter (cross-instance room broadcast) and a third client for the Redis emitter (cross-instance direct send).
|
|
81
|
-
- **Authentication is mandatory.** Every client starts `unauthorized` and must emit `authenticate` within `authenticateTimeout` (default 10s) or it is disconnected. Success joins the client to the default rooms and starts a keep-alive ping.
|
|
82
|
-
- **Room joins are opt-in by default.** Without a bound `VALIDATE_ROOM_HANDLER`, every `join` request is silently rejected -- security-by-default, not a bug.
|
|
46
|
+
Socket.IO needs a running server, but components initialize before the server exists. Five mechanisms bridge that gap and keep every client on a security-by-default path:
|
|
83
47
|
|
|
84
|
-
|
|
48
|
+
| Mechanism | What happens |
|
|
49
|
+
|---|---|
|
|
50
|
+
| Post-start hook | `binding()` runs during `initialize()`, resolves bindings, and registers a hook. The hook builds `SocketIOServerHelper` and binds it to `SOCKET_IO_INSTANCE` only after `start()` runs. |
|
|
51
|
+
| Runtime detection | `RuntimeModules.detect()` picks Node.js (Socket.IO attaches to `node:http.Server` directly) or Bun (`@socket.io/bun-engine` is dynamically imported and wired into `server.reload()`). See the [runtime comparison](./api#runtime-specific-behavior). |
|
|
52
|
+
| Redis fan-out | The connection you bind is never consumed directly. The helper calls `duplicateClient()` three times: a pub/sub pair for the Redis adapter, and a third client for the Redis emitter. |
|
|
53
|
+
| Mandatory authentication | Every client starts `unauthorized`. It must emit `authenticate` within `authenticateTimeout` (default 10s) or it gets disconnected. Success joins the client to the default rooms and starts a keep-alive ping. |
|
|
54
|
+
| Opt-in rooms | No `VALIDATE_ROOM_HANDLER` bound means every `join` request is rejected. That's security-by-default, not a bug. |
|
|
85
55
|
|
|
86
|
-
|
|
56
|
+
## Common tasks
|
|
57
|
+
|
|
58
|
+
### Restrict CORS for production
|
|
59
|
+
|
|
60
|
+
Bind `SERVER_OPTIONS` before registering the component. The default (`cors.origin: '*'`) is for local development only.
|
|
87
61
|
|
|
88
62
|
```typescript
|
|
89
63
|
import type { ServerOptions } from 'socket.io';
|
|
@@ -94,39 +68,49 @@ this.bind<Partial<ServerOptions>>({ key: SocketIOBindingKeys.SERVER_OPTIONS }).t
|
|
|
94
68
|
this.component(SocketIOComponent);
|
|
95
69
|
```
|
|
96
70
|
|
|
97
|
-
|
|
71
|
+
### Send a message from a service
|
|
72
|
+
|
|
73
|
+
`SOCKET_IO_INSTANCE` is bound by the component after the server starts, so resolve it lazily - never `@inject` it in a constructor. Full pattern in [Inject the helper in a service or controller](./usage#inject-the-helper-in-a-service-or-controller).
|
|
98
74
|
|
|
99
75
|
```typescript
|
|
100
76
|
this.io.send({ destination: userId, payload: { topic: 'notification', data } });
|
|
101
77
|
```
|
|
102
78
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
|
|
79
|
+
### Scale Redis beyond a single node
|
|
80
|
+
|
|
81
|
+
Swap `RedisSingleHelper` for `RedisClusterHelper` or `RedisSentinelHelper`. Both satisfy the `IRedisHelper` interface the component validates against. See [Redis connection alternatives](./usage#redis-connection-alternatives) for the full example.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { RedisClusterHelper } from '@venizia/ignis-helpers';
|
|
85
|
+
|
|
86
|
+
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION }).toValue(
|
|
87
|
+
new RedisClusterHelper({
|
|
88
|
+
name: 'socket-io-redis-cluster',
|
|
89
|
+
nodes: [{ host: 'redis-node-1', port: 6379 }],
|
|
90
|
+
autoConnect: false,
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Look up a default, binding key, or event name
|
|
96
|
+
|
|
97
|
+
Every `DEFAULT_SERVER_OPTIONS` field, the binding key table, system events, default rooms, and the client state machine live in the [Full Reference](./api#configuration-reference).
|
|
98
|
+
|
|
99
|
+
## See also
|
|
100
|
+
|
|
101
|
+
- [Usage & Examples](./usage) - full setup steps, server-side usage, client helper, advanced patterns
|
|
102
|
+
- [Full Reference](./api) - architecture, configuration reference, method signatures, internals, types
|
|
103
|
+
- [Error Reference](./errors) - error conditions and troubleshooting
|
|
104
|
+
- [Socket.IO Helper](/extensions/helpers/socket-io/) - full `SocketIOServerHelper` + `SocketIOClientHelper` API reference
|
|
105
|
+
- [WebSocket Component](../websocket/) - Bun-only alternative
|
|
106
|
+
- [Real-Time Chat tutorial](/guides/tutorials/realtime-chat) - building a chat app with Socket.IO
|
|
107
|
+
- [Socket.IO Documentation](https://socket.io/docs/) - official docs
|
|
108
|
+
- [Socket.IO Redis Adapter](https://socket.io/docs/v4/redis-adapter/) - horizontal scaling guide
|
|
109
|
+
- [@socket.io/bun-engine](https://github.com/socketio/bun-engine) - Bun runtime support
|
|
110
|
+
- [2026-02-06: Socket.IO Integration Fix](/changelogs/2026-02-06-socket-io-integration-fix) - lifecycle timing fix + Bun runtime support
|
|
127
111
|
|
|
128
112
|
**Files:**
|
|
129
113
|
|
|
130
|
-
- [`packages/core/src/components/socket-io/component.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/components/socket-io/component.ts)
|
|
131
|
-
- [`packages/core/src/components/socket-io/common/keys.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/components/socket-io/common/keys.ts)
|
|
132
|
-
- [`packages/core/src/components/socket-io/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/components/socket-io/common/types.ts)
|
|
114
|
+
- [`packages/core-server/src/components/socket-io/component.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/components/socket-io/component.ts) - `SocketIOComponent`
|
|
115
|
+
- [`packages/core-server/src/components/socket-io/common/keys.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/components/socket-io/common/keys.ts) - `SocketIOBindingKeys`
|
|
116
|
+
- [`packages/core-server/src/components/socket-io/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/components/socket-io/common/types.ts) - `IServerOptions`, `DEFAULT_SERVER_OPTIONS`
|