Skip to content
This repository has been archived by the owner on Jul 17, 2023. It is now read-only.

Commit

Permalink
feat(koa): Add websocket support via WebsocketHook
Browse files Browse the repository at this point in the history
  • Loading branch information
robertrossmann committed Jan 18, 2018
1 parent 85832b2 commit 34b51eb
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 39 deletions.
85 changes: 47 additions & 38 deletions packages/koa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ const atlas = new Atlas({
koa: {
proxy: true,
},
// If set to an object, will be used to load all middleware found in this module into the
// Koa instance
middleware: {
module: 'path/to/middleware',
config: {
bodyparser: {},
// ...
}
}
}
}
}
Expand All @@ -50,46 +59,9 @@ atlas.services.http
atlas.services.http.server
```

### MiddlewareHook

To add middleware to the Koa instance, it is recommended that this hook is used for that. It allows you to specify from which module the middleware should be loaded and adds it to Koa for you when the application starts.

#### MiddlewareHook Dependencies

- `service:koa`: A koa service to load the middleware into

```js
import { Atlas } from '@atlas.js/atlas'
import * as Koa from '@atlas.js/koa'

const atlas = new Atlas({
config: {
hooks: {
middleware: {
// The path to the module, relative to root, which should be loaded and
// the exported middleware added to the Koa service
module: 'middleware',
middleware: {
// You can define configuration options for your middleware here.
// The key must match the exported middleware name.
}
}
}
}
})

atlas.service('http', Koa.Service)
atlas.hook('middleware', Koa.MiddlewareHook, {
aliases: {
'service:koa': 'http'
}
})
await atlas.start()
```

#### Example middleware module

Here is an example middleware module that the `MiddlewareHook` expects to find.
Here is an example middleware module that the service supports.

```js
// middleware.js
Expand Down Expand Up @@ -178,9 +150,46 @@ export default {
}
```

### WebsocketHook

This hook extends the Koa instance with websocket protocol support, using [koa-websocket][koa-websocket].

#### WebsocketHook Dependencies

- `service:koa`: A Koa service on which to add the websocket protocol support

```js
const atlas = new Atlas({
config: {
hooks: {
websocket: {
// This has the same structure and purpose as the Koa service's middleware config: it allows
// you to add websocket-specific middleware to the server.
middleware: {
module: 'path/to/websocket/middleware',
config: {}
},
// This goes directly to the websocket protocol's constructor. Note that you should not
// use `host`, `port` or `server` options since the server instance is re-used from the
// underlying Koa server and creating a new http server could cause unwanted side-effects.
// See: https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
listen: {},
}
}
}
})
```

Once attached to a Koa servise, the websocket interface is accessible as per the library's definition via `koa.ws`, which in Atlas it would be:

```js
atlas.services.http.ws
```

## License

See the [LICENSE](LICENSE) file for information.

[koa-settings]: http://koajs.com/#settings
[http-settings]: https://nodejs.org/api/http.html#http_class_http_server
[koa-websocket]: https://www.npmjs.com/package/koa-websocket
40 changes: 40 additions & 0 deletions packages/koa/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/koa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"@atlas.js/errors": "^0.1.1",
"@atlas.js/hook": "^1.0.2",
"@atlas.js/service": "^1.0.2",
"koa": "^2.3.0"
"koa": "^2.3.0",
"koa-websocket": "^4.1.0"
},
"engines": {
"node": "^8.3.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/koa/src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Server from './server'
import ContextHook from './context'
import WebsocketHook from './websocket'

export {
Server,
ContextHook,
WebsocketHook,
}
51 changes: 51 additions & 0 deletions packages/koa/src/websocket.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Hook from '@atlas.js/hook'
import websocket from 'koa-websocket'
import middleware from './middleware'

class WebsocketHook extends Hook {
static requires = [
'service:koa',
]

static defaults = {
middleware: {
module: 'websocket/middleware',
config: {},
},
listen: null,
}

afterPrepare() {
const koa = this.component('service:koa')
const config = this.config

websocket(koa)
this.log.debug('websocket:attach')

// Apply websocket middleware
if (config.middleware) {
middleware(koa.ws, this.atlas.require(config.middleware.module), config.middleware.config)
}
}

afterStart() {
const koa = this.component('service:koa')

koa.ws.listen({
...this.config.listen,
server: koa.server,
})

this.log.info({ addrinfo: koa.server.address() }, 'listening')
}

async beforeStop() {
this.log.info('websocket:close')

await new Promise((resolve, reject) =>
this.component('service:koa').ws.server.close(err =>
err ? reject(err) : resolve()))
}
}

export default WebsocketHook
Loading

0 comments on commit 34b51eb

Please sign in to comment.