Enrutamiento de nombres de dominio
A partir de 0.28.0, fibjs
el objeto mq.Routing admite el método HOST como enrutamiento de nombres de dominio.
1
2
3
4
5
6
7
8
9
10
11
12const mq = require('mq')
const rt = new mq.Routing();
// support *.fibjs.org in Routing
rt.host('*.fibjs.org', ...)
// support api.fibjs.org in Routing
rt.host('api.fibjs.org', ...)
// support fibjs.org in Routing
rt.host('fibjs.org', ...)
rt.append('host', 'fibjs.org', ...)
Veamos algunos ejemplos.
Ejemplo sencillo
Manejadores de archivos simples
Supongamos que el nombre de dominio fibjs.org se ha vinculado a la máquina donde se encuentra nuestra aplicación (para fines de prueba, también puede lograr este efecto vinculante modificando los Hosts localmente), y esperamos poder file.fibjs.org
descargar recursos de archivos en FILE_DIR directorio en la máquina, podemos hacer esto:
1
2
3
4
5
6const mq = require('mq')
const http = require('http')
const fileRoutes = new mq.Routing();
// support file.fibjs.org in Routing
fileRoutes.host('file.fibjs.org', http.fileHandler(FILE_DIR))
Host de recursos front-end
Un escenario típico es que la aplicación front-end compilada puede publicarse en la máquina, por ejemplo, guardarse en /home/frontend/assets/
el directorio
1
2
3
4
5/home/frontend/assets/index.html
/home/frontend/assets/200.html
/home/frontend/assets/app.839ca9.js
/home/frontend/assets/common.537a50.js
/home/frontend/assets/chunk.d45858.js
Y si queremos obtener estos recursos a través de festatic.fibjs.org, podemos escribir así:
1fileRoutes.host('festatic.fibjs.org', http.fileHandlers('/home/frontend/assets/'))
servidor API
Supongamos que hay servidores API en su máquina y desea unificarlos a api.fibjs.org
este nombre de dominio, pero asignar diferentes rutas, como por ejemplo:
Servidor API | Uso | Camino |
---|---|---|
http://127.0.0.1:3001 | Servicio de usuario | /usuario |
http://127.0.0.1:8080 | negocio1 | /biz1 |
http://127.0.0.1:9007 | Biz2 | /biz2 |
Entonces tú puedes:
1
2
3
4
5
6
7
8
9
10const mq = require('mq')
const apiRoutes = new mq.Routing();
// proxyTo 是代理请求到对应 origin 的函数
apiRoutes.host('api.fibjs.org', {
'/user': (req) => proxyTo(req, `http://127.0.0.1:3001`),
'/biz1': (req) => proxyTo(req, `http://127.0.0.1:8080`),
'/biz2': (req) => proxyTo(req, `http://127.0.0.1:9007`),
})
Además, si desea que la ruta '/biz1' solo acepte solicitudes POST http, puede:
1
2
3
4
5
6
7
8
9const mq = require('mq')
const apiRoutes = new mq.Routing();
apiRoutes.host('api.fibjs.org', {
'/user': (req) => proxyTo(req, `http://127.0.0.1:3001`),
'/biz1': apiRoutes.post((req) => proxyTo(req, `http://127.0.0.1:8080`)),
'/biz2': (req) => proxyTo(req, `http://127.0.0.1:9007`),
})
Tenga en cuenta que api.fibjs.org debe estar vinculado a la máquina actual
Ejemplo complejo
Si no hay otras declaraciones, en el siguiente ejemplo, existen las siguientes funciones:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 生成带特定 host 的请求
function getRequest({
path = '/',
host = 'www.fibjs.org'
}) {
const req = new http.Request()
req.value = path
req.addHeader('host', host)
return req
}
// 以 method 尝试对 routes 发起一个 header: host=host 的请求
function invokePathFromHost (path, host, method = 'GET') {
const req = getRequest({ path, host })
req.method = method
mq.invoke(routes, req)
const result = req.response.body.readAll()
return result ? result.toString() : result
}
Desvío de nombres de dominio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36const mq = require('mq')
const http = require('http')
const assert = require('assert')
const routes = new mq.Routing();
routes.host('api.fibjs.org', [
{
'/user/information': req => req.response.json({name: 'xicilion'}),
},
req => req.response.body.rewind()
])
// routes.host 方法可以多次调用
routes.host('*.fibjs.org', [
{
'/': req => req.response.json({message: 'I am in root'}),
'/index.html': req => req.response.body.write(`<html><body>hello fibjs</body></html>`),
'/index.js': req => req.response.body.write(`console.log('hello world')`),
'*': (req, domain) => {
req.response.json({message: 'I am fallback'})
}
},
req => req.response.body.rewind()
])
assert.equal( invokePathFromHost('/', 'www.fibjs.org'), `{"message":"I am in root"}` )
assert.equal( invokePathFromHost('/index.html', 'static.fibjs.org'), `<html><body>hello fibjs</body></html>` )
assert.equal( invokePathFromHost('/index.js', 'static.fibjs.org'), `console.log('hello world')` )
assert.equal( invokePathFromHost('/user/information', 'api.fibjs.org'), JSON.stringify({name: 'xicilion'}) )
try {
invokePathFromHost('/', 'fibjs.org')
} catch (error) {
assert.equal(error, 'Error: Routing: unknown routing: fibjs.org')
}
A continuación, solo necesita montar las rutas en el ejemplo anterior en un servidor http(s) y podrá comenzar a funcionar. Si el servidor escucha el puerto predeterminado de la máquina (generalmente 80), entonces se realizará una distribución de tráfico basada en el nombre de dominio Se han configurado los servicios de puerta de enlace para diferentes rutas; esto significa que para completar la misma función, solo puede usar mq.Routing de fibjs sin tener que instalar servicios de puerta de enlace tradicionales como nginx/apache/tomcat/iis.