# Berichten uitwisselen met de Total Messaging Service

> Schakel het TMS-WebSocket-eindpunt in en laat externe clients gepubliceerde berichten ontvangen, berichten naar je app sturen en haar functies aanroepen.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: nl
Content-SHA256: cd32bc41e4e954ee160358a3a19a70999c813c9359e35e1c1a72d38936335917
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

TMS (Total Messaging Service) is een kleine berichtenbus bovenop een WebSocket. Je schakelt hem in het bestand `config` in met `$tms : true`; het eindpunt is `/$tms/` en `secret_tms` is het token dat elke client in de header `x-token` moet sturen (een verkeerd token sluit de verbinding met code 4001, en een adres dat meer dan 5 keer faalt wordt een tijdje geblokkeerd). Wanneer een client verbindt, ontvangt hij een `meta`-bericht dat opsomt wat de app publiceert, wat ze accepteert en wat ze kan.

Drie dingen kunnen worden aangeboden, elk beschreven door een schema in hetzelfde formaat `name:Type` als de `input` van een actie:

- `NEWPUBLISH(name, schema)` declareert een bericht dat de app **verstuurt**; `PUBLISH(name, value)` stuurt het naar elke client die erom vroeg door `{ type: 'subscribers', subscribers: [name] }` te sturen.
- `NEWSUBSCRIBE(name, schema, callback)` declareert een bericht dat de app **ontvangt**: een client stuurt `{ type: 'subscribe', id: name, data: {...} }` en `callback(message, client)` draait alleen als de gegevens geldig zijn. De gevalideerde gegevens staan in `message.response` (`message.error` is daar altijd `null`) en `client` is de afzender.
- `NEWCALL(name, schema, callback)` declareert een functie die de client **aanroept**: de client stuurt `{ type: 'call', id: name, data: {...}, callbackid: '1' }` en de app antwoordt met hetzelfde bericht met `success: true` en het resultaat in `data`, of met `error: true` wanneer de gegevens ongeldig zijn. `callback(data, done, client)` levert het resultaat met `done(null, result)`.

`null` als schema van `NEWPUBLISH` of `NEWSUBSCRIBE` verwijdert de declaratie. De officiële client van Total.js (`TMSCLIENT`) spreekt dit protocol voor je vanuit een andere Total.js-app; elke WebSocket-client werkt.

`UNSUBSCRIBE(name, [callback])` verwijdert de listeners van een bericht dat de applicatie ontvangt: alleen `callback` als je die meegeeft, anders alle. Het geeft `true` terug als er iets is verwijderd en `false` als er niets te verwijderen was.

```text config
$tms : true
secret_tms : my-tms-token
```

```js definitions/tms.js
NEWPUBLISH('news', 'title:String');

NEWSUBSCRIBE('orders', 'id:String, qty:Number', function(message, client) {
	MAIN.orders.push(message.response);
});

NEWCALL('sum', 'a:Number, b:Number', function(data, done) {
	done(null, { total: data.a + data.b });
});

MAIN.orders = [];
```

```js controllers/tms.js
exports.install = function() {
	ROUTE('POST /news/ @json', news);
	ROUTE('GET /orders/', orders);
	ROUTE('GET /unsubscribe/', unsubscribe);
};

function news($) {
	PUBLISH('news', { title: $.body.title });
	$.success();
}

function orders($) {
	$.json(MAIN.orders);
}

function unsubscribe($) {
	const first = UNSUBSCRIBE('orders');
	const second = UNSUBSCRIBE('orders');
	$.json({ first: first, second: second });
}
```
