# Trocar mensagens com o Total Messaging Service

> Ative o endpoint WebSocket do TMS e deixe que clientes externos recebam mensagens publicadas, enviem mensagens à sua aplicação e chamem as suas funções.

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

O TMS (Total Messaging Service) é um pequeno barramento de mensagens sobre um WebSocket. Ativa-se no ficheiro `config` com `$tms : true`; o endpoint é `/$tms/` e `secret_tms` é o token que todos os clientes têm de enviar no cabeçalho `x-token` (um token errado fecha a ligação com o código 4001, e um endereço que falhe mais de 5 vezes é bloqueado durante algum tempo). Quando um cliente se liga, recebe uma mensagem `meta` que lista o que a aplicação publica, o que aceita e o que sabe fazer.

Podem expor-se três coisas, cada uma descrita por um schema no mesmo formato `name:Type` do `input` de uma ação:

- `NEWPUBLISH(name, schema)` declara uma mensagem que a aplicação **envia**; `PUBLISH(name, value)` envia-a a todos os clientes que a pediram enviando `{ type: 'subscribers', subscribers: [name] }`.
- `NEWSUBSCRIBE(name, schema, callback)` declara uma mensagem que a aplicação **recebe**: um cliente envia `{ type: 'subscribe', id: name, data: {...} }` e `callback(message, client)` só corre quando os dados são válidos. Os dados validados estão em `message.response` (`message.error` é sempre `null` aí) e `client` é quem envia.
- `NEWCALL(name, schema, callback)` declara uma função que o cliente **chama**: o cliente envia `{ type: 'call', id: name, data: {...}, callbackid: '1' }` e a aplicação responde com a mesma mensagem com `success: true` e o resultado em `data`, ou com `error: true` quando os dados são inválidos. `callback(data, done, client)` produz o resultado com `done(null, result)`.

Passar `null` como schema de `NEWPUBLISH` ou `NEWSUBSCRIBE` remove a declaração. O cliente oficial do Total.js (`TMSCLIENT`) fala este protocolo por si a partir de outra aplicação Total.js; qualquer cliente WebSocket serve.

`UNSUBSCRIBE(name, [callback])` remove os ouvintes de uma mensagem que a aplicação recebe: apenas `callback` quando o passa, todos quando não. Devolve `true` quando removeu algo e `false` quando não havia nada a remover.

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