# Scambiare messaggi con il Total Messaging Service

> Attiva l'endpoint WebSocket di TMS e lascia che client esterni ricevano messaggi pubblicati, inviino messaggi alla tua app e ne chiamino le funzioni.

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

TMS (Total Messaging Service) è un piccolo bus di messaggi sopra un WebSocket. Si attiva nel file `config` con `$tms : true`; l'endpoint è `/$tms/` e `secret_tms` è il token che ogni client deve inviare nell'header `x-token` (un token errato chiude la connessione con il codice 4001, e un indirizzo che fallisce più di 5 volte viene bloccato per un po'). Quando un client si connette riceve un messaggio `meta` che elenca ciò che l'app pubblica, ciò che accetta e ciò che sa fare.

Si possono esporre tre cose, ciascuna descritta da uno schema nello stesso formato `name:Type` dell'`input` di un'azione:

- `NEWPUBLISH(name, schema)` dichiara un messaggio che l'app **invia**; `PUBLISH(name, value)` lo invia a ogni client che lo ha richiesto inviando `{ type: 'subscribers', subscribers: [name] }`.
- `NEWSUBSCRIBE(name, schema, callback)` dichiara un messaggio che l'app **riceve**: un client invia `{ type: 'subscribe', id: name, data: {...} }` e `callback(message, client)` viene eseguita solo quando i dati sono validi. I dati validati sono in `message.response` (`message.error` lì è sempre `null`) e `client` è il mittente.
- `NEWCALL(name, schema, callback)` dichiara una funzione che il client **chiama**: il client invia `{ type: 'call', id: name, data: {...}, callbackid: '1' }` e l'app risponde con lo stesso messaggio con `success: true` e il risultato in `data`, oppure con `error: true` quando i dati non sono validi. `callback(data, done, client)` produce il risultato con `done(null, result)`.

Passare `null` come schema di `NEWPUBLISH` o `NEWSUBSCRIBE` rimuove la dichiarazione. Il client ufficiale di Total.js (`TMSCLIENT`) parla questo protocollo per te da un'altra app Total.js; va bene qualsiasi client WebSocket.

`UNSUBSCRIBE(name, [callback])` rimuove i listener di un messaggio che l'applicazione riceve: solo `callback` se lo passi, tutti altrimenti. Restituisce `true` se ha rimosso qualcosa e `false` se non c'era nulla da rimuovere.

```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 });
}
```
