Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded protocols #286

Merged
merged 20 commits into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
14719f1
Embedded protocols
benoitvidis Apr 25, 2019
f4f2215
Update src/protocols/1/native-protocols/http/index.md
scottinet Apr 25, 2019
99dc9c1
Update src/protocols/1/native-protocols/http/index.md
scottinet Apr 25, 2019
072435a
Update src/protocols/1/native-protocols/http/index.md
scottinet Apr 25, 2019
5ba8495
Update src/protocols/1/native-protocols/mqtt/index.md
scottinet Apr 25, 2019
ef9ab32
Update src/protocols/1/native-protocols/mqtt/index.md
scottinet Apr 25, 2019
3d3c4bb
Update src/protocols/1/native-protocols/socketio/index.md
scottinet Apr 25, 2019
0d0fd24
Update src/protocols/1/native-protocols/socketio/index.md
scottinet Apr 25, 2019
114541e
Update src/protocols/1/native-protocols/websocket/index.md
scottinet Apr 25, 2019
033094f
Update src/protocols/1/native-protocols/websocket/index.md
scottinet Apr 25, 2019
244aa75
Update src/protocols/1/native-protocols/websocket/index.md
scottinet Apr 25, 2019
7cf94f7
Update src/protocols/1/native-protocols/mqtt/index.md
scottinet Apr 25, 2019
28ec005
Update src/protocols/1/native-protocols/mqtt/index.md
scottinet Apr 25, 2019
2590ed4
Update src/protocols/1/native-protocols/mqtt/index.md
scottinet Apr 25, 2019
fb2dcca
Update src/protocols/1/native-protocols/socketio/index.md
scottinet Apr 25, 2019
e8cf2f0
Update src/protocols/1/native-protocols/socketio/index.md
scottinet Apr 25, 2019
4b534ff
Update src/protocols/1/native-protocols/socketio/index.md
scottinet Apr 25, 2019
b18f4b1
Merge branch '2-dev' into KZL-950-embedded-protocols
benoitvidis Apr 25, 2019
7f91019
Merge branch '2-dev' into KZL-950-embedded-protocols
scottinet Apr 26, 2019
02843dc
websocket protocol - add heartbeat configuration
benoitvidis Apr 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/protocols/1/essentials/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ order: 0

# Getting Started

Kuzzle has native support for the following network protocols: HTTP, Websocket and Socket.io.
Kuzzle has native support for the following network protocols: [HTTP]({{ site_base_path }}protocols/1/native-protocols/http), [MQTT]({{ site_base_path }}protocols/1/native-protocols/mqtt) (disabled by default), [Websocket]({{ site_base_path }}protocols/1/native-protocols/websocket) and [Socket.io]({{ site_base_path }}protocols/1/native-protocols/socketio).

However, any number of protocols can be implemented, adding new network capabilities.

Expand All @@ -18,8 +18,6 @@ Protocols are provided with objects to interact with Kuzzle:
* [EntryPoint]({{ site_base_path }}protocols/1/entrypoint): base communication layer (declare user connections, forward API requests, ...)
* [context]({{ site_base_path }}protocols/1/context): utilities and object constructors not directly related to network communications

Protocol implementation example: [MQTT](https://github.com/kuzzleio/protocol-mqtt)

---

## Prerequisites
Expand Down
6 changes: 6 additions & 0 deletions src/protocols/1/methods/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
layout: full.html.hbs
title: Protocol Methods
description: Extend Kuzzle communication capabilities
order: 0
---
32 changes: 32 additions & 0 deletions src/protocols/1/native-protocols/http/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
layout: full.html.hbs
title: HTTP
order: 0
---

# HTTP

## Configuration

The protocol can be configured via the [kuzzlerc configuration file]({{ site_base_path }}guide/1/essentials/configuration/), under the ``server > protocols > http`` section.

| Option | Type | Description | Default |
|---|---|---|---|
| ``enabled`` | <pre>boolean</pre> | Enable/Disable HTTP protocol support | ``true`` |
| ``maxFormFileSize`` | <pre>string</pre> | Maximum size of requests sent via http forms | ``1mb`` |
| ``maxEncodingLayers`` | <pre>integer</pre> | Maximum number of encoding layers that can be applied to an http message, using the Content-Encoding header. This parameter is meant to prevent abuses by setting an abnormally large number of encodings, forcing Kuzzle to allocate as many decoders to handle the incoming request | ``3`` |
| ``allowCompression`` | <pre>boolean</pre> | Enable support for compressed requests, using the Content-encoding header. Currently supported compression algorithms: gzip, deflate, identity. Note: "identity" is always an accepted value, even if compression support is disabled | ``true`` |

### Configure listening port

<div class="alert alert-warning">
HTTP, WebSocket and Socket.IO protocols share the same underlying server instance. Modifying the listening port will impact all these three protocols.
</div>

By default, Kuzzle listens to the ``7512`` port.

The port can be modified under the ``server > port`` section of [Kuzzle configuration]({{ site_base_path }}guide/1/essentials/configuration/).

## Limitations

Due to the synchronous nature of the HTTP protocol, real-time messaging is not supported.
6 changes: 6 additions & 0 deletions src/protocols/1/native-protocols/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
layout: full.html.hbs
title: Native Protocols
description: Extend Kuzzle communication capabilities
order: 0
---
185 changes: 185 additions & 0 deletions src/protocols/1/native-protocols/mqtt/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
layout: full.html.hbs
title: MQTT
order: 0
---
# MQTT

<div class="alert alert-warning">
By default, the MQTT protocol is disabled in Kuzzle configuration.
</div

---

## Configuration

The protocol can be configured via the [kuzzlerc configuration file]({{ site_base_path }}guide/1/essentials/configuration/), under the ``server > protocols > mqtt`` section.

| Option | Type | Description | Default |
|---|---|---|---|
| ``enabled`` | <pre>boolean</pre> | Enable/Disable the MQTT protocol support | ``false`` |
| ``allowPubSub`` | <pre>boolean</pre> | Allow MQTT pub/sub capabilities or restrict to Kuzzle requests only | ``false`` |
| ``developmentMode`` | <pre>boolean</pre> | Switches ``responseTopic`` back to a regular public topic | ``false`` |
| ``disconnectDelay`` | <pre>integer</pre> | Delay in ms to apply between a disconnection notification is received and the connection is actually removed | 250 |
| ``requestTopic`` | <pre>string</pre> | Name of the topic listened by the plugin for requests | ``"Kuzzle/request"`` |
| ``responseTopic`` | <pre>string</pre> | Name of the topic clients should listen to get requests result | ``"Kuzzle/response"`` |
| ``server`` | <pre>object</pre> | Constructor options pased to underlying mqtt server. See [mosca documentation](https://github.com/mcollina/mosca/wiki/Mosca-advanced-usage#other-options-of-mosca-the-ones-we-inserted-in-our-moscasettings-var) for further reference. | ``{port: 1883}`` |

example:

``.kuzzlerc``
```json
{
"server": {
"protocols": {
"mqtt": {
"allowPubSub": true
}
}
}
}
```

## How to use

### Sending an API request and getting the response

By default, the MQTT protocol listens to the ``Kuzzle/request`` MQTT topic (see [configuration](#configuration)) for requests to the [Kuzzle API]({{ site_base_path }}api/1/essentials/connecting-to-kuzzle/).

It then forwards Kuzzle response to the ``Kuzzle/response`` MQTT topic, **and only to the client who made the initial request**.

The order of responses is not guaranteed to be the same than the order of requests. To link a response to its original request, use the ``requestId`` attribute: the response will have the same ``requestId`` than the one provided in the request.

Example using [MQTT Node module](https://www.npmjs.com/package/mqtt): _to use a CLI client, you will need to enable development mode. Please refer to [the dedicated section below](#development-mode) for instruction and examples_

```javascript
const
mqtt = require('mqtt'),
client = mqtt.connect({host: 'localhost'});

// Sending a volatile message
client.publish('Kuzzle/request', JSON.stringify({
index: 'index',
collection: 'collection',
controller: 'realtime',
action: 'publish',
requestId: 'some unique ID',
body: { some: "message" }
}));

// Getting Kuzzle's response
client.on('message', (topic, raw) => {
const message = JSON.parse(Buffer.from(raw));

// API results topic
if (topic === 'Kuzzle/response') {
// Response to our "publish" request
if (message.requestId === 'some unique ID') {
console.log('Message publication result: ', message);
}
}
});
```

### Using Kuzzle subscriptions

Kuzzle allows to [subscribe](https://docs.kuzzle.io/api/1/controller-realtime/subscribe/) to messages and events using advanced filters.

Each time a subscription is sent, a dedicated MQTT topic is created, named after the ``channel`` property issued by Kuzzle.

Here are the steps to perform a Kuzzle subscription using MQTT:

- Send a subscription request to Kuzzle
- Listen to the request's response to ge the ``channel`` identifier
- Subscribe to the MQTT topic named after this channel identifier

Example using [MQTT Node module](https://www.npmjs.com/package/mqtt):

```javascript
const
mqtt = require('mqtt'),
client = mqtt.connect({host: 'localhost'}),
channels = [];

// Sending a volatile message
client.publish('Kuzzle/request', JSON.stringify({
index: 'index',
collection: 'collection',
controller: 'realtime',
action: 'subscribe',
requestId: 'some unique ID',
body: {
term: {
some: 'filter'
}
}
}));

// Getting Kuzzle's response
client.on('message', (topic, raw) => {
const message = JSON.parse(Buffer.from(raw));

// API results topic
if (topic === 'Kuzzle/response') {
// Response to our "publish" request
if (message.requestId === 'some unique ID') {
channels.push(message.result.channel);
client.subscribe(message.result.channel);
}
}
else if (channels.indexOf(topic) !== -1) {
// Subscription notification
console.log('Notification: ', message);
}
});
```

## Authorizations

### Publishing

If ``allowPubSub`` is set to ``false``, clients can only publish to the ``requestTopic`` topic (defaults to ``Kuzzle/request``).

If ``allowPubSub`` is set to ``true``, clients are only forbidden to publish to the ``responseTopic`` topic (defaults to ``Kuzzle/response``).

<div class="alert alert-warning">
Wildcards subcriptions are not allowed
</div

If a client tries to publich to an unauthorized topic, his connection will immediately be shut down by the server.

### Subscribing

Subscription attempts to the ``requestTopic`` topic (defaults to ``Kuzzle/request``) are ignored: client requests can only be listened by the MQTT server.

## Development mode

The MQTT ``Kuzzle/response`` topic is by default a special topic that acts as a private channel. Each client receives its own responses only, offering a simple first security layer.

While this behavior is urgently recommended in production, it can bring a small drawback when testing and developing applications: it does not allow using most CLI tools.
Many CLI tools, such as Mosquitto offer two separate binaries, one for subscribing and one for publishing. These act as two different clients and the subscriber won't receive any response sent to the publisher by default.

To use these tools, one can enable the **development mode**, in which ``Kuzzle/response`` will act as a regular public topic.

<div class="alert alert-warning">
Do not use development mode in production!
</div

To enable development mode, you will need to **both** set ``NODE_ENV`` environment variable to ``development`` and set the mqtt protocol ``developmentMode`` to ``true``:

```
# starting kuzzle with mqtt development mode enabled
NODE_ENV=development \
kuzzle_server__protocols__mqtt__enabled=true \
kuzzle_server__protocols__mqtt__developmentMode=true \
./bin/kuzzle start

# client 1
$ mosquitto_sub -t Kuzzle/response

# client 2
$ mosquitto_pub -t Kuzzle/request -m '{"controller": "server", "action": "now"}'

# client 1
$ {"requestId":"83a63209-7633-4884-9f1a-c490ce446ddf","status":200,"error":null,"controller":"server","action":"now","collection":null,"index":null,"volatile":null,"result":{"now":1509967201489}}
```
25 changes: 25 additions & 0 deletions src/protocols/1/native-protocols/socketio/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
layout: full.html.hbs
title: Socket.IO
order: 0
---
# Socket.IO

## Configuration

The protocol can be configured via the [kuzzlerc configuration file]({{ site_base_path }}guide/1/essentials/configuration/), under the ``server > protocols > socketio`` section.

| Option | Type | Description | Default |
|---|---|---|---|
| ``enabled`` | <pre>boolean</pre> | Enable/Disable Socket.IO protocol support | ``true`` |
| ``origins`` | <pre>string</pre> | Value of Access-Control-Allow-Origin header to answer the upgrade request | ``*:*`` |

### Configure listening port

<div class="alert alert-warning">
HTTP, WebSocket and Socket.IO protocols share the same underlying server instance. Modifying the listening port will impact all these three protocols.
</div>

By default, Kuzzle listens to the ``7512`` port.

The port can be modified under the ``server > port`` section of [Kuzzle configuration]({{ site_base_path }}guide/1/essentials/configuration/).
25 changes: 25 additions & 0 deletions src/protocols/1/native-protocols/websocket/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
layout: full.html.hbs
title: WebSocket
order: 0
---
# WebSocket

## Configuration

The protocol can be configured via the [kuzzlerc configuration file]({{ site_base_path }}guide/1/essentials/configuration/), under the ``server > protocols > websocket`` section.

| Option | Type | Description | Default |
|---|---|---|---|
| ``enabled`` | <pre>boolean</pre> | Enable/Disable WebSocket protocol support | ``true`` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing heartbeat documentation (kuzzleio/kuzzle#1289)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

| ``heartbeat`` | <pre>integer</pre> | The time, in milliseconds, between the server's PING requests. Setting this value to ``0`` disables PING/PONG requests entirely. | ``60000`` |

### Configure listening port

<div class="alert alert-warning">
HTTP, WebSocket and Socket.IO protocols share the same underlying server instance. Modifying the listening port will impact all these three protocols.
</div>

By default, Kuzzle listens to the ``7512`` port.

The port can be modified under the ``server > port`` section of [Kuzzle configuration]({{ site_base_path }}guide/1/essentials/configuration/).