# Intercambia mensajes con el Total Messaging Service

> Activa el endpoint WebSocket de TMS y deja que clientes externos reciban mensajes publicados, envíen mensajes a tu aplicación y llamen a sus funciones.

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

TMS (Total Messaging Service) es un pequeño bus de mensajes sobre un WebSocket. Se activa en el archivo `config` con `$tms : true`; el endpoint es `/$tms/` y `secret_tms` es el token que todo cliente debe enviar en la cabecera `x-token` (un token incorrecto cierra la conexión con el código 4001, y una dirección que falla más de 5 veces se bloquea durante un tiempo). Cuando un cliente se conecta recibe un mensaje `meta` que lista lo que la aplicación publica, lo que acepta y lo que sabe hacer.

Se pueden exponer tres cosas, cada una descrita por un schema en el mismo formato `name:Type` que el `input` de una acción:

- `NEWPUBLISH(name, schema)` declara un mensaje que la aplicación **envía**; `PUBLISH(name, value)` lo envía a todos los clientes que lo pidieron enviando `{ type: 'subscribers', subscribers: [name] }`.
- `NEWSUBSCRIBE(name, schema, callback)` declara un mensaje que la aplicación **recibe**: un cliente envía `{ type: 'subscribe', id: name, data: {...} }` y `callback(message, client)` se ejecuta solo cuando los datos son válidos. Los datos validados están en `message.response` (`message.error` siempre es `null` ahí) y `client` es quien lo envía.
- `NEWCALL(name, schema, callback)` declara una función que el cliente **llama**: el cliente envía `{ type: 'call', id: name, data: {...}, callbackid: '1' }` y la aplicación responde con el mismo mensaje con `success: true` y el resultado en `data`, o con `error: true` cuando los datos no son válidos. `callback(data, done, client)` produce el resultado con `done(null, result)`.

Pasar `null` como schema de `NEWPUBLISH` o `NEWSUBSCRIBE` elimina la declaración. El cliente oficial de Total.js (`TMSCLIENT`) habla este protocolo por ti desde otra aplicación Total.js; sirve cualquier cliente WebSocket.

`UNSUBSCRIBE(name, [callback])` elimina los oyentes de un mensaje que la aplicación recibe: solo `callback` cuando lo pasas, todos cuando no. Devuelve `true` cuando eliminó algo y `false` cuando no había nada que eliminar.

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