使用 Node.js 定制地理空间服务框架
19806 文章评分:
3.7
使用 Node.js 定制地理空间服务框架
匿名 2016年10月27日,星期四
在我看来,地理空间服务框架(GSF)最强大的功能之一,就是它构建于 Node.js 之上。这有很多优点,但我特别想谈谈一点,那就是它提供了极大的定制灵活性。
下面我将展示一个简单但强大的定制示例。但在开始之前,我想先简要概述一下 GSF 和 Node.js。
Node.js 是一个基于 Chrome V8 JavaScript 引擎构建的 JavaScript 运行时。它采用事件驱动、非阻塞 I/O 模型,使其轻量且高效。对于这篇博文而言,Node.js 的重要性在于,它是一个强大、可扩展的 Web 应用后端,并且使用的是几乎每个网站都在使用的语言——JavaScript。
我们通过加入 GSF 改进了 ENVI 服务引擎。GSF 是一个基于 Node.js 的轻量但强大的框架,可以为任何规模的组织提供可扩展的地理空间智能。我喜欢将其描述为一个“信使”系统,它提供了一种在 Web 与我们的各种产品或“引擎”(如 ENVI、IDL 等,它们提供分析功能)之间进行通信的方式。
GSF 在设计上将其 Node.js 代码公开。这允许对产品进行无限定制,以适应其需要驻留的任何架构。它是一个模块化系统,具有不同的模块,可以开启/关闭,甚至可以复制和扩展。这使得定制变得容易且安全。
这些模块之一称为请求处理器(Request Handler)。该模块为 GSF 提供端点服务。这可以简单地是基于 REST 的调用,也可以是一个网页,或者更好的是两者兼有。
在开发一个 ENVI Web 客户端演示程序时(该程序获取托管在 Amazon S3 上的栅格数据并传递给 GSF 进行分析),我发现没有简单的方法来列出我的 S3 存储中可用的数据。在探索解决此问题的方法时,我意识到可以简单地利用 Node.js 的能力来完成此任务。
将 GSF 已安装的 aws-sdk 包导入到我的请求处理器后,我编写了一个简单的函数来使用该包列出 S3 存储数据中的所有 .dat 文件,并将该信息返回给我的前端 Web 应用程序以供接收和显示。
以下是稍作修改的请求处理器代码,附有解释每个部分的注释。
//Import express, used by node.js to setup rest endpoints
var express = require('express');
//Import AWS, used to interact with Amazon Web Services including S3 storage
var aws = require('aws-sdk');
//Extra tools that should be included in request handlers
var extend = require('util')._extend;
var defaultConfig = require('./config.json');
/**
* Dynamic Request Handler
*/
function DynUiHandler() {
var s3Bucket, s3;
//Setup config options
var config = {};
extend(config, defaultConfig);
//Grab information for S3 from config.json
s3Workspace = config.S3Root;
s3Bucket = config.S3Bucket;
// Setup S3
s3 = new aws.S3(config);
/**
* List files in the s3 bucket.
* @param {object} req - The Express request object.
* @param {object} res - The Express response object.
*/
function listS3Data(req, res) {
//Take the parameter passed from the REST call and set that as the bucket to be accessed in the call to s3.
var params = {
Bucket: req.params.bucket
};
//Call the S3 package's built in listObjects function to return what is avaiable in the specified bucket
s3.listObjects(params, function(err, data) {
//check if error occured and if so, halt and report it to client.
if (err) {
var code = err.code || 500;
var message = err.message || err;
res.status(code).send({
error: message
});
}
// If no error, push every object found in the response with a '.dat' extension to an array that will be returned to client
else {
var files = [];
//Look at each file contained in data returned by s3.listObjects()
data.Contents.forEach(function(file) {
//Searches for files with .dat in the bucket requested
if(file.Key.endsWith('.dat')){
//If found, store that file information in the files array.
files.push(file);
}
});
}
//send the files array containing metadata of all .dat files found.
res.send(files);
});
};
//Initialize request handler, run when GSF starts up.
this.init = function(app) {
// Set up request handler to host the html subdirectory as a webpage.
app.use('/dynui/', require('express').static(__dirname + '/html/'));
// Set up a rest call that runs listS3Data and supplies the accomponying bucket parameter.
app.get('/s3data/:bucket', listS3Data);
};
}
//
module.exports = DynUiHandler;
重启服务器后,我可以通过在浏览器中输入以下内容来访问我的 REST 端点:
http://localhost:9191/s3data/mybucket
这将返回 "mybucket" 内容的 JSON 数据。
利用这些信息,我能够在我的应用程序界面内为用户提供关于他们可用数据的实时信息。
这是一个简单的示例,展示了如何定制一个现成的请求处理器来增强我的 Web 演示程序。然而,以模块化方式修改这样一个强大系统的源代码,提供了一种安全的方法,可以将 GSF 塑造成恰好符合您自身架构所需的形式和形态。
也许这只是我个人的看法,但我更倾向于这种方式,而不是为了适应我一无所知的闭源代码而重构我自己现有的架构。