Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/xadillax/gensokyo
An RPC framework implemented in Node.js with https://github.com/XadillaX/illyria2 which is in use of Huaban.com.
https://github.com/xadillax/gensokyo
Last synced: 5 days ago
JSON representation
An RPC framework implemented in Node.js with https://github.com/XadillaX/illyria2 which is in use of Huaban.com.
- Host: GitHub
- URL: https://github.com/xadillax/gensokyo
- Owner: XadillaX
- License: mit
- Created: 2015-03-31T06:09:17.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2023-06-21T02:28:07.000Z (over 1 year ago)
- Last Synced: 2024-11-01T09:51:35.500Z (12 days ago)
- Language: JavaScript
- Homepage:
- Size: 399 KB
- Stars: 10
- Watchers: 3
- Forks: 1
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Gensokyo [~東方幻想鄉~]
[![Gensokyo](http://img.shields.io/npm/v/gensokyo.svg)](https://www.npmjs.org/package/gensokyo)
[![Gensokyo](http://img.shields.io/npm/dm/gensokyo.svg)](https://www.npmjs.org/package/gensokyo)
[![License](https://img.shields.io/npm/l/gensokyo.svg?style=flat)](https://www.npmjs.org/package/gensokyo)
[![Dependency Status](https://david-dm.org/XadillaX/gensokyo.svg)](https://david-dm.org/XadillaX/gensokyo)![Gensokyo](https://raw.githubusercontent.com/XadillaX/gensokyo/master/gensokyo.jpg)
花瓣网主站服务化 & Project-Her 核心框架模块。
## Installation
Install `gensokyo` via npm:
```sh
$ [sudo] npm install gensokyo -g
```## Usage
Go into any directory, and then type
```sh
$ gensokyo new PROJECT_NAME
```You will find a new project directory named `PROJECT_NAME` is created.
Inside this directory, there are:
```folder
.
├── config
│ ├── config.server.js
│ ├── config.zookeeper.js
│ └── index.js
├── controller
│ └── echoController.js
├── filter
│ └── echoFilter.js
├── gensokyo.js
├── log
│ └── deleteme
├── node_modules
│ ├── gensokyo
│ └── nomnom
├── package.json
└── router
└── echoRouter.js
```### Config
`config` includes some configuration files. for example, you want to add a `config.foo.js` to system, you should add this file into `config` and add a new line in `index.js` to let others can access to it.
#### rootPath
If you want use a specified project path, use `rootPath` in parameter `options` while `Gensokyo.createServer`;
#### noZookeeper
Use `noZookeeper` in parameter `options` while you won't use zookeeper to manage your nodes.
#### aliasRules
Use `aliasRules` if you need expose API with their alias names. (refer [here](https://github.com/XadillaX/illyria2/blame/0de8a8bfeb0f98b8508f10d0815a80924e8f020a/README.md#L58))
#### metric
Use `metric` if you want to monit the metrics. It needs `reportPort` to open a web server to report metrics.
##### riemann
You can send metrics to Riemann intervally if you include `riemann` in `metric`.
```json
metric: {
reportPort: 3333,riemann: {
port: 5555,
host: "10.0.17.179",
transport: "tcp",
sendInterval: 60000
}
}
```### Controller
`controller` includes 真·logic code.
Each controller should named as `*Controller.js`.
This is the code in pre-build controller file `echoController`:
```javascript
var util = require("util");
var Controller = require("gensokyo").Controller;var EchoController = function(gensokyo) {
Controller.call(this, gensokyo);
};util.inherits(EchoController, Controller);
EchoController.prototype.echo1 = function(req, resp, next) {
this.logger.info("echo1");
next();
};EchoController.prototype.echo2 = function(req, resp, next) {
this.logger.info("echo2");
resp.message.ok = true;// 测试人品
if(Number.random(1, 100) < 50) {
resp.error("You're unlucky!");
return;
}next();
};module.exports = EchoController;
```### Filter
There are two types of filters: **before-filter** and **after-filter**.
They are all in `filter` directory and named as `*Filter.js`.
This is the example filter code:
```javascript
var util = require("util");
var Filter = require("gensokyo").Filter;var EchoFilter = function(gensokyo) {
Filter.call(this, gensokyo);
};util.inherits(EchoFilter, Filter);
EchoFilter.prototype.before1 = function(req, resp, next) {
this.logger.info("before1");
next();
};EchoFilter.prototype.before2 = function(req, resp, next) {
this.logger.info("before2");
next();
};EchoFilter.prototype.after1 = function(req, resp, next) {
this.logger.info("after1");
next();
};EchoFilter.prototype.after2 = function(req, resp, next) {
this.logger.info("after2");
next();
};module.exports = EchoFilter;
```### Router
#### Router Chain
Each server router is a logic chain which is like:
```text
filter1 -> filter2 -> filter... -> logic1 -> logic2 -> logic... -> filter'1 -> filter'2 -> filter'...
```When server received a message from client, a router chain will be triggered.
The filters before logic are called **before-filter**s and the rests are **after-filter**s.
The process can stop at any step and send the client back a message.
If the process is finished and no any message sent back, Gensokyo will send the message which is dealed in `resp.message` automatically.
#### Router Defination
All the routers are defined in files named `*Router.js` which are under directory `router`.
You should defined a JSON object contains `router name => router chain` key-value pair.
> **Attention:** if your router filename is `fooRouter.js`, all the filter and logic function should in `fooController.js` and `fooFilter.js`.
About the defination, refer to the code below:
```javascript
/**
* each router example:
*
* + single controller
* - foo : "bar"
* - foo : [ "bar" ]
* - foo : { ctrller: "bar" }
*
* + multi controller
* - foo : [ [ "bar1", "bar2" ] ]
* - foo : { ctrller: [ "bar1", "bar2" ] }
*
* + with single/multiple `before filter`
* - foo : [ "before", "bar" ] ///< with only 2 elements in the array
* - foo : [ "before", [ "bar1", "bar2" ] ] ///< with only 2 elements in the array
* - foo : [ [ "before1", "before2" ], [ "bar" ] ] ///< with only 2 elements in the array
* - foo : { before: "before", ctrller: "bar" }
* - foo : { before: [ "before1", "before2" ], ctrller: "bar" }
*
* + with single/multiple `after filter`
* - foo : { ctrller: ..., after: [ ... ] }
* - foo : { ctrller: ..., after: "bar" }
*
* + with both `before` and `after` filters
* - foo : [ "before", "bar", "after" ] ///< must with 3 elements in the array
* - foo : [ [ ... ], [ ... ], [ ... ] ] ///< must with 3 elements in the array
* - foo : { before: "before" / [ ... ], ctrller: "bar" / [ ... ], after: "after" / [ ... ]}
*/
```So here's an example of `echoRouter.js`:
```javascript
module.exports = {
echo1 : [ "before1", "echo2" ],
echo2 : [ "before1", [ "echo1", "echo2" ], "after1" ],
echo3 : "echo1",
echo4 : { before: [ "before1" ], ctrller: "echo1" }
};
```The code above said
> When server received a router named `echo -> echo2` (`echoRouter.js` and `echo2 chain`), the server will trigger `echo2` chain, so the chain with `EchoFilter::before1`, `EchoController::echo1`, `EchoController::echo2` and `EchoFilter::after1` is triggered.
### Incoming & Outcoming Message
#### Incoming Message
Incoming message usually appears in `function(req, resp, next)`.
`req` is so-called incoming message.
##### req.gensokyo
The Gencokyo object.
##### req.server
The server object.
##### req.router
The router JSON object.
##### req.param
Incoming parameters are inside this value.
##### req.socket
The socket object.
##### req.time
Incoming time.
##### req.routerString()
Return a string like `"echo.echo1"`.
#### Outcoming Message
`resp` is so-called outcoming message.
##### resp.gensokyo
The Gensokyo object.
##### resp.server
The server object.
##### resp.message
You can store all the information you want to send to client in it.
For example:
```javascript
resp.message.foo = "bar";
resp.message.ok = false;
```After calling `resp.send` manually or after the whole chain, this message will be send to client:
```json
{
"foo": "bar",
"ok": false
}
```##### resp.send()
Send the stored message to client.
If called once, it won't make any sense while calling again.
##### resp.error()
Send an error message to client.
If called once, it won't make any sense while calling again.
#### Helper
```javascript
var helper = require("gensokyo").helper;
```##### Global
###### helper.global.getModel(modelName)
Get the model in `/model/Model.js`.
##### ... (Under Development)