 <img src="assets/images/sugo-hub-banner.png" alt="Title Banner"
                    height="148"
                    style="height:148px"
/>


<!---
This file is generated by ape-tmpl. Do not update manually.
--->

<!-- Badge Start -->
<a name="badges"></a>

[![Build Status][bd_travis_shield_url]][bd_travis_url]
[![npm Version][bd_npm_shield_url]][bd_npm_url]
[![JS Standard][bd_standard_shield_url]][bd_standard_url]

[bd_repo_url]: https://github.com/realglobe-Inc/sugo-hub
[bd_travis_url]: http://travis-ci.org/realglobe-Inc/sugo-hub
[bd_travis_shield_url]: http://img.shields.io/travis/realglobe-Inc/sugo-hub.svg?style=flat
[bd_travis_com_url]: http://travis-ci.com/realglobe-Inc/sugo-hub
[bd_travis_com_shield_url]: https://api.travis-ci.com/realglobe-Inc/sugo-hub.svg?token=
[bd_license_url]: https://github.com/realglobe-Inc/sugo-hub/blob/master/LICENSE
[bd_codeclimate_url]: http://codeclimate.com/github/realglobe-Inc/sugo-hub
[bd_codeclimate_shield_url]: http://img.shields.io/codeclimate/github/realglobe-Inc/sugo-hub.svg?style=flat
[bd_codeclimate_coverage_shield_url]: http://img.shields.io/codeclimate/coverage/github/realglobe-Inc/sugo-hub.svg?style=flat
[bd_gemnasium_url]: https://gemnasium.com/realglobe-Inc/sugo-hub
[bd_gemnasium_shield_url]: https://gemnasium.com/realglobe-Inc/sugo-hub.svg
[bd_npm_url]: http://www.npmjs.org/package/sugo-hub
[bd_npm_shield_url]: http://img.shields.io/npm/v/sugo-hub.svg?style=flat
[bd_standard_url]: http://standardjs.com/
[bd_standard_shield_url]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg

<!-- Badge End -->


<!-- Description Start -->
<a name="description"></a>

Hub server of SUGOS

<!-- Description End -->


<!-- Overview Start -->
<a name="overview"></a>


SUGO-Hub works as a hub to connect [SUGO-Actor][s_u_g_o_actor_url]s and [SUGO-Caller][s_u_g_o_caller_url]s.


<!-- Overview End -->


<!-- Sections Start -->
<a name="sections"></a>

<!-- Section from "doc/guides/00.TOC.md.hbs" Start -->

<a name="section-doc-guides-00-t-o-c-md"></a>

Table of Contents
----------------

- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [Advanced Usage](#advanced-usage)
  * [Using Redis Server](#using-redis-server)
  * [Define HTTP Endpoints](#define-http-endpoints)
  * [Define HTTP Middlewares](#define-http-middlewares)
  * [Use Authentication](#use-authentication)
  * [Register Local Actors](#register-local-actors)
- [License](#license)
- [Links](#links)


<!-- Section from "doc/guides/00.TOC.md.hbs" End -->

<!-- Section from "doc/guides/10.Requirements.md.hbs" Start -->

<a name="section-doc-guides-10-requirements-md"></a>

Requirements
-----

<a href="https://nodejs.org">
  <img src="assets/images/nodejs-banner.png"
       alt="banner"
       height="40"
       style="height:40px"
  /></a>
<a href="https://docs.npmjs.com/">
  <img src="assets/images/npm-banner.png"
       alt="banner"
       height="40"
       style="height:40px"
  /></a>

+ [Node.js ( >=7.6 )][node_download_url]
+ [npm ( >=4 )][npm_url]

[node_download_url]: https://nodejs.org/en/download/
[npm_url]: https://docs.npmjs.com/


<!-- Section from "doc/guides/10.Requirements.md.hbs" End -->

<!-- Section from "doc/guides/21.Installation.md.hbs" Start -->

<a name="section-doc-guides-21-installation-md"></a>

Installation
-----

```bash
$ npm install sugo-hub --save
```


<!-- Section from "doc/guides/21.Installation.md.hbs" End -->

<!-- Section from "doc/guides/22.Usage.md.hbs" Start -->

<a name="section-doc-guides-22-usage-md"></a>

Usage
---------

```javascript
#!/usr/bin/env node

/**
 * This is an example to setup hub server
 */

'use strict'

const sugoHub = require('sugo-hub')

async function tryExample () {
  // Start sugo-hub server
  let hub = sugoHub({
    // Options here
  })

  await hub.listen(3000)

  console.log(`SUGO Cloud started at port: ${hub.port}`)
}

tryExample().catch((err) => console.error(err))

```

By default, SUGOS-Cloud provides WebSocket interfaces with following URLs:

| URL | Description |
| --- | ----------- |
| `/actors` | WebSocket namespace for [SUGO-Actors][sugo_actor_url] |
| `/callers` | WebSocket namespace for [SUGO-Callers][sugo_caller_url] |
| `/observers` | WebSocket namespace for [SUGO-Observers][sugo_observer_url] |


For more detail, see [API Guide](./doc/api/api.md)


<!-- Section from "doc/guides/22.Usage.md.hbs" End -->

<!-- Section from "doc/guides/23.Advanced Usage.md.hbs" Start -->

<a name="section-doc-guides-23-advanced-usage-md"></a>

Advanced Usage
---------

SUGO cloud also provide bunch of options for building more complex applications.

### Using Redis Server

By default, SUGO-Hub save state to json files. This may cause performance slow down on production.
It is recommended to setup redis server for storage.

```javascript
#!/usr/bin/env node

/**
 * This is an example to setup hub server with redis
 */

'use strict'

const sugoHub = require('sugo-hub')

async function tryRedisExample () {
  let hub = sugoHub({
    // Using redis server as storage
    storage: {
      // Redis setup options (see https://github.com/NodeRedis/node_redis)
      redis: {
        host: '127.0.0.1',
        port: '6379',
        db: 1
      }
    },
    endpoints: { /* ... */ },
    middlewares: [ /* ... */ ],
    static: [ /* ... */ ]
  })

  await hub.listen(3000)

  console.log(`SUGO Cloud started at port: ${hub.port}`)
}
tryRedisExample().catch((err) => console.error(err))

```

### Define HTTP Endpoints

SUGO-Hub uses [Koa][koa_url] as http framework. You can define custom koa handlers on `endpoints` field.

```javascript
#!/usr/bin/env node

/**
 * This is an example to setup hub server with endpoints
 */

'use strict'

const sugoHub = require('sugo-hub')

async function tryExample () {
  let hub = sugoHub({
    storage: { /* ... */ },
    // HTTP route handler with koa
    endpoints: {
      '/api/user/:id': {
        'GET': (ctx) => {
          let { id } = ctx.params
          /* ... */
          ctx.body = { /* ... */ }
        }
      }
    },
    middlewares: [ /* ... */ ],
    static: [ /* ... */ ]
  })

  await hub.listen(3000)

  console.log(`SUGO Cloud started at port: ${hub.port}`)
}
tryExample().catch((err) => console.error(err))

```

### Define HTTP Middlewares

For cross-endpoint handling, add koa middleware function to `middlewares` field.

Note that static middlewares are provided as build-in middleware and you can serve static files by just setting directory names to `static` field.

```javascript
#!/usr/bin/env node

/**
 * This is an example to setup hub server with middlewares
 */

'use strict'

const sugoHub = require('sugo-hub')

async function tryMiddleareExample () {
  let hub = sugoHub({
    storage: { /* ... */ },
    // HTTP route handler with koa
    endpoints: { /* ... */ },
    // Custom koa middlewares
    middlewares: [
      async function customMiddleware (ctx, next) {
        /* ... */
        await next()
      }
    ],
    // Directory names to server static files
    static: [
      'public'
    ]
  })

  await hub.listen(3000)

  console.log(`SUGO Cloud started at port: ${hub.port}`)
}
tryMiddleareExample().catch((err) => console.error(err))

```


### Use Authentication

By providing `authenticate` filed, you can authenticate sockets connecting.

```javascript
#!/usr/bin/env node

/**
 * This is an example to setup hub server with aut
 */

'use strict'

const sugoHub = require('sugo-hub')

async function tryAuthExample () {
  let hub = sugoHub({
    storage: { /* ... */ },
    endpoints: { /* ... */ },
    /**
     * Auth function
     * @param {Object} socket - A socket connecting
     * @param {Object} data - Socket auth data
     * @returns {Promise.<boolean>} - OK or not
     */
    authenticate (socket, data) {
      let tokenStates = { /* ... */ }
      let ok = !!tokenStates[ data.token ]
      return Promise.resolve(ok)
    },
    middlewares: [ /* ... */ ],
    static: [ /* ... */ ]
  })

  await hub.listen(3000)

  console.log(`SUGO Cloud started at port: ${hub.port}`)
}

tryAuthExample().catch((err) => console.error(err))

```


### Register Local Actors

If you want to use actors on the same environment with hub, pass actors instances to `localActors` option of hub.

```javascript
#!/usr/bin/env node

/**
 * This is an example to setup hub server with local actors
 */

'use strict'

const sugoHub = require('sugo-hub')
const sugoActor = require('sugo-actor')

async function tryLocalExample () {
  let hub = sugoHub({
    storage: { /* ... */ },
    endpoints: { /* ... */ },
    middlewares: [ /* ... */ ],
    static: [ /* ... */ ],

    /**
     * Local actors for the hub
     * @type {Object<string, SugoActor>}
     */
    localActors: {
      'my-actor-01': sugoActor({
        modules: {
          say: {
            sayYes: () => 'Yes from actor01'
          }
        }
      })
    }
  })

  // Local actors automatically connect to the hub when it start listening
  await hub.listen(3000)

  console.log(`SUGO Cloud started at port: ${hub.port}`)
}

tryLocalExample().catch((err) => console.error(err))

```

<!-- Section from "doc/guides/23.Advanced Usage.md.hbs" End -->


<!-- Sections Start -->


<!-- LICENSE Start -->
<a name="license"></a>

License
-------
This software is released under the [Apache-2.0 License](https://github.com/realglobe-Inc/sugo-hub/blob/master/LICENSE).

<!-- LICENSE End -->


<!-- Links Start -->
<a name="links"></a>

Links
------

+ [SUGO-Actor][s_u_g_o_actor_url]
+ [SUGO-Caller][s_u_g_o_caller_url]
+ [SUGO-Observer][s_u_g_o_observer_url]
+ [Koa][koa_url]
+ [SUGOS][sugos_url]
+ [Realglobe, Inc.][realglobe,_inc__url]

[s_u_g_o_actor_url]: https://github.com/realglobe-Inc/sugo-actor
[s_u_g_o_caller_url]: https://github.com/realglobe-Inc/sugo-caller
[s_u_g_o_observer_url]: https://github.com/realglobe-Inc/sugo-observer
[koa_url]: https://github.com/koajs/koa
[sugos_url]: https://github.com/realglobe-Inc/sugos
[realglobe,_inc__url]: http://realglobe.jp

<!-- Links End -->
