Skip to content

Commit 2cb84fc

Browse files
committed
Identifier exclusion
1 parent 58a943c commit 2cb84fc

31 files changed

+584
-106
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
### Added
1111

1212
- First major release
13+
- Support for excluding a consumer-defined socket instance by identifier
1314

1415
### Fixed
1516

README.md

+37-7
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,14 @@ In case of execution errors, the event broadcast is retried automatically, while
265265

266266
Events are broadcast to all websocket clients, including clients established in context of current event context user.
267267
To influence event broadcasting based on current context user, the annotation `@websocket.user` or `@ws.user` is available on
268-
event type level and entity type element level (alternatives include `@websocket.broadcast.user` or `@ws.broadcast.user`):
268+
event type level and event type element level (alternatives include `@websocket.broadcast.user` or `@ws.broadcast.user`):
269269

270270
Valid annotation values are:
271271

272-
- **Entity type level**:
272+
- **Event type level**:
273273
- `'excludeCurrent'`: Current event context user is statically excluded everytime during broadcasting to websocket clients.
274274
All websocket clients established in context to that user are not respected during event broadcast.
275-
- **Entity type element level**:
275+
- **Event type element level**:
276276
- `'excludeCurrent'`: Current event context user is dynamically excluded during broadcasting to websocket clients,
277277
based on the value of the annotated event type element.
278278
If truthy, all websocket clients established in context to that user are not respected during event broadcast.
@@ -282,7 +282,8 @@ Valid annotation values are:
282282
It is possible to broadcast events to a subset of clients. By entering or exiting contexts, the server can be instructed to
283283
determined based on the event type, to which subset of clients the event shall be emitted. To specify which data parts of the
284284
event are leveraged for setting up the context, the annotation `@websocket.context` or `@ws.context` is available on
285-
event type element level (alternatives include `@websocket.broadcast.context` or `@ws.broadcast.context`):
285+
event type element level (alternatives include `@websocket.broadcast.context` or `@ws.broadcast.context`). For static contexts
286+
the annotation can also be used on event type level, providing a static event context string.
286287

287288
```cds
288289
event received {
@@ -357,20 +358,49 @@ over remote distribution via Redis.
357358

358359
For Socket.IO (`kind: socket.io`) contexts are implemented leveraging [Socket.IO rooms](https://socket.io/docs/v4/rooms/).
359360

361+
### Event Client Identifier
362+
363+
Events are broadcast to all websocket clients, including clients that performed certain action. In some cases, the
364+
websocket client shall not be informed about the event, that was triggered by the same client (maybe via a different channel, e.g. OData).
365+
Therefore, websocket clients can be identified optionally by a unique identifier provided as URL parameter option `?id=<globally unique value>`.
366+
The annotation `@websocket.identifier` or `@ws.identifier` is available on event type level and event type element level
367+
to influence event broadcasting based websocket client identifier (alternatives include `@websocket.broadcast.identifier` or `@ws.broadcast.identifier`):
368+
369+
Valid annotation values are:
370+
371+
- **Event type level**:
372+
- Provide a static unique identifier to exclude the client from event broadcasting
373+
- **Event type element level**:
374+
- Value from event data for the annotated element is used as unique identifier to exclude the websocket client from event broadcasting
375+
- First annotated element with an defined event data value is taken
376+
377+
The unique identifier can be provided for a websocket client as follows:
378+
379+
- WS Standard:
380+
```js
381+
socket = new WebSocket("ws://localhost:4004/ws/chat?id=1234");
382+
```
383+
- Socket.IO:
384+
```js
385+
const socket = io("/chat?id=1234", { path: "/ws" });
386+
```
387+
360388
### Event Emit Headers
361389

362390
The websocket implementation allows to provide event emit headers to dynamically control websocket processing.
363391
The following headers are available:
364392

365-
- `excludeCurrentUser: boolean`: Exclude current user from event broadcasting (see section Event User)
366-
- `contexts: String[]`: Provide an array of context strings to identify a subset of clients (see section Event Contexts)
393+
- `excludeCurrentUser: boolean, wsExcludeCurrentUser: boolean`: Exclude current user from event broadcasting (see section Event User)
394+
- `contexts: String[], wsContexts: String[]`: Provide an array of context strings to identify a subset of clients (see section Event Contexts)
395+
- `identifier: String, wsIdentifier: String`: Exclude an websocket client via its identifier (see section Event Client Identifier)
367396

368397
Emitting events with headers can be performed as follows:
369398

370399
```js
371-
await srv.emit("customContextHeaderEvent", req.data, {
400+
await srv.emit("customEvent", { ... }, {
372401
contexts: ["..."],
373402
excludeCurrentUser: req.data.type === "1",
403+
identifier: "...",
374404
});
375405
```
376406

eslint.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module.exports = [
4040
rules: {
4141
strict: ["error"],
4242
curly: ["error"],
43-
"no-unused-vars": ["off"],
43+
"no-unused-vars": ["error", { argsIgnorePattern: "err|req|res|next", caughtErrors: "none" }],
4444
"no-restricted-modules": ["off"],
4545
"no-eval": ["error"],
4646
"no-implied-eval": ["error"],

jest.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module.exports = {
1111
coverageReporters: ["lcov", "text"],
1212
coverageThreshold: {
1313
global: {
14-
branches: 75,
14+
branches: 80,
1515
functions: 90,
1616
lines: 90,
1717
statements: 90,

package-lock.json

+47-47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"express": "^4.19.2",
4747
"redis": "^4.6.13",
4848
"socket.io": "^4.7.5",
49-
"ws": "^8.15.1"
49+
"ws": "^8.17.0"
5050
},
5151
"devDependencies": {
5252
"@cap-js-community/websocket": "./",
@@ -60,10 +60,10 @@
6060
"@types/express": "^4.17.21",
6161
"eslint": "^9.1.1",
6262
"eslint-config-prettier": "^9.1.0",
63-
"eslint-plugin-jest": "^28.2.0",
63+
"eslint-plugin-jest": "^28.3.0",
6464
"eslint-plugin-n": "17.3.1",
6565
"express-request-proxy": "^2.2.2",
66-
"globals": "15.0.0",
66+
"globals": "15.1.0",
6767
"jest": "^29.7.0",
6868
"passport": "0.7.0",
6969
"prettier": "^3.2.4",

0 commit comments

Comments
 (0)