MATLAB是用于技术计算的高级语言。 它在易于使用的环境中集成了计算,可视化和编程功能,其中问题和解决方案以熟悉的数学符号表示。 世界各地有许多用MATLAB编写并由数百万科学家和工程师开发的项目。 人们从MATLAB获得的各种实验和操作的数据可以用于驱动Web应用程序,但是有两个障碍:
- MATLAB理解矩阵格式的数据,而Web应用程序更喜欢JSON或XML的数据。
- 通常,数据是在MATLAB程序中创建和使用的,这限制了开发人员希望拥有的关于保存数据,使用数据等的自由度。
如果MATLAB提供JSON数据,并且Web应用程序可以使用来自MATLAB的JSON数据创建精彩的东西,则创建应用程序会容易得多。
在本文中,我们将开发一个小示例,以演示如何使MATLAB和MEAN堆栈协同工作。
关于网络应用
该Web应用程序将涉及从MATLAB到浏览器的实时数据传输。 为简单起见,我们将从MATLAB传输当前时间,并将其显示在浏览器中。 我们将使用JSONlab (工具箱)在MATLAB中对JSON文件进行编码/解码。 将使用MEAN堆栈创建Web应用程序。 如果您不熟悉MEAN堆栈,建议您在继续之前阅读文章“ MEAN堆栈简介” 。
JSONlab简介
JSONlab是针对MATLAB语言的JSON编码器/解码器的免费开源实现。 它可用于将MATLAB数据结构(数组,结构,单元格,结构数组和单元格数组)转换为JSON格式的字符串,或将JSON文件解码为MATLAB数据。
它使我们可以访问四个函数: loadjson()
, savejson()
, loadubjson()
和saveubjson()
。 最后两个函数用于处理UBJSON格式 。 loadjson()
用于将JSON字符串转换为相关的MATLAB对象。 在我们的项目中,我们仅使用savejson()
函数将MATLAB对象(单元格,结构或数组)转换为JSON字符串。 可以按以下方式使用它:
json = savejson(rootname, obj, filename)
json = savejson(rootname, obj, opt)
json = savejson(rootname, obj, 'param1', value1, 'param2', value2, ...)
由于我们必须编写文件,因此我们将使用第一个签名。 它返回一个JSON字符串,并将该字符串写入文件。
JSONlab安装
首先, 下载JSONlab ,解压缩存档,然后使用以下命令将文件夹的路径添加到MATLAB的路径列表中:
addpath('/path/to/jsonlab');
如果要永久添加此路径,则需要输入pathtool
,浏览到JSONlab根文件夹并将其添加到列表中。 完成后,您必须单击“保存”。 然后,在MATLAB中运行rehash
,然后键入which loadjson
。 如果看到输出,则表明JSONlab已正确安装。
MATLAB代码
我们需要当前时间,因此我们将使用clock
命令。 它以[year month day hour minute seconds]
格式返回包含当前日期和时间的六元素日期向量。 为了重复获取时间,我们将clock
命令置于无限的while
循环中。 因此,我们获得了实时数据,直到在MATLAB的命令窗口上使用Ctrl+C
终止脚本执行为止。
以下代码实现了此想法:
format shortg;
y=0;
while y = 0
% c = [year month day hour minute seconds]
c=clock;
% Rounding every value to an integer
c=fix(c);
x.clock=c;
% accessing the 4th column of c, i.e hours
x.hours=c(:,4);
% accessing the 5th column of c ,i.e minutes
x.minutes=c(:,5);
% accessing the 6th column of c, i.e seconds
x.seconds=c(:,6);
% converting x into JSON and writing as matlabData.json
savejson('',x,'data/matlabData.json');
end
在我们的项目中,我们关心小时,分钟和秒。 上面的代码中使用的fix(c)
函数将矩阵的所有元素四舍五入为最接近的整数。 要获取hour
数据,我们需要矩阵第 4列的值,因此我们使用命令c(:,4)
。 使用相同的方法,我们检索分钟和秒。
我们将把clock
及其一些单独的变量分别发送到Web应用程序,以显示从MATLAB对象到JSON的不同数据类型的转换。 虽然clock
数据将转换为Array
,但小时,分钟和秒的值将转换为Number
,我们将在后面看到。
在我们的项目中,我们将使用savejson()
函数使用JSON格式在文件matlabData.json
转换和写入变量x
。 为简单起见, rootname
参数将为空字符串。
使用前面的代码,我们需要的所有MATLAB代码都已完成。 现在,一旦运行脚本,我们可以观察到JSON文件是在data
文件夹中创建的,并且文件中的数据会自动保持更新。 JSON文件内容的示例如下所示:
{
"hours": 19,
"minutes": 28,
"seconds": 28,
"clock": [2015,5,27,19,28,28]
}
我们将观看此文件,并使用Node.js读取最新数据。 现在开始构建Web应用程序。
网络应用
现在,我们将来自MATLAB的数据转换为JSON并将其存储在文件中,我们可以独立读取该文件并通过观察其更改来获取数据。 此操作完全独立于MATLAB。 在本文的其余部分,我将假定您对socket.io和MEAN堆栈都有一定的了解,即使我们仅使用它们的基本概念。
让我们开始编写Web应用程序。
创建Package.json文件
首先从我们的应用程序开始,让我们定义项目的依赖关系。 为此,我们将创建一个如下所示的package.json文件:
{
"name": "matlab-mean-demo",
"version": "1.0.0",
"description": "A demo web-app using Matlab and MEAN stack",
"main": "server.js",
"dependencies": {
"express": "latest",
"mongoose": "latest",
"socket.io": "^1.2.0"
}
创建文件后,在项目的根文件夹中运行npm install
,以便将安装所有依赖项。 如果您不熟悉npm ,建议您阅读npm入门指南-Node Package Manager 。
服务器端代码
代码的这一部分涉及Node.js,Express和MongoDB的使用。 服务器执行的操作是:
- 提供
index.html
文件 - 观看和读取JSON文件中的数据
- 使用MongoDB将数据保存在数据库中
- 使用socket.io将数据发送到浏览器
我们将在根文件夹中创建一个名为server.js
的文件,在该文件中,我们将编写描述所有功能所需的代码。
我们使用Express提供静态文件:
// Defining the root directory for static files
app.use(express.static(__dirname + '/app'));
// Serving the static HTML
app.get("/", function(req, res) {
res.sendfile("/index.html");
});
每当将请求发送到/
,都会处理存储在app
目录中的index.html
文件。
要查看文件中的任何更改,请使用fs.watch()
并在每次更改时读取文件,请使用fs.readFile()
。 一旦检测到更改,便会读取文件并检索数据。 整个过程使用以下代码完成:
fs.watch('folderName',function(event,filename){
fs.readFile('folderName' + filename, function(err,data){
console.log(data);
});
});
与客户端建立连接并开始获取数据后,我们将执行两个操作:
- 使用socket.io的
emit()
函数将数据发送到浏览器 - 使用猫鼬中间件将数据保存在MongoDB中
为了执行第二个操作,我们创建数据的架构,然后基于该架构创建模型。 这是通过下面显示的代码完成的:
// Creation of the schema
var dataSchema = mongoose.Schema({
clock: Array,
hours: Number,
minutes: Number,
seconds: Number
});
// Creating a model based on schema
var appData = mongoose.model('appData', dataSchema);
在上一个代码片段的最后一个语句中,我们基于定义的架构创建模型。 传递给函数的第一个参数是模型所使用的集合的单数名称。 猫鼬会自动为集合指定复数名称。 所以在这里, appData
是一个appDatas
集合的模型。
获取新数据时,我们将使用最新数据创建该架构的新实例,并使用save()
方法将其保存在数据库中。 该实例称为文档 。 在下面的代码中, savingData
是一个文档。
这部分的最终代码如下所示:
var express = require('express');
var mongoose = require('mongoose');
var fs = require('fs');
var app = express();
//Make a connection to MongoDB
mongoose.connect('MongoDB://localhost/matlabMeanDemo');
var io = require('socket.io')(app.listen(3000));
//Defining the root directory for static files
app.use(express.static(__dirname + '/app'));
//serving the static HTML
app.get("/", function (req, res) {
res.sendfile("/index.html");
});
var appData;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback() {
var dataSchema;
dataSchema = mongoose.Schema({
clock: Array,
hours: Number,
minutes: Number,
seconds: Number
});
appData = mongoose.model('appData', dataSchema);
//Sending and receiving data
io.on('connection', function (socket) {
fs.watch('data', function (event, filename) {
fs.readFile('data/' + filename, function (err, data) {
if (!err) {
try {
var x = JSON.parse(data);
socket.emit('updated', x);
// Create a new instance of appData model
// i.e also known as a document
var savingData = new appData({
clock: x.clock,
hours: x.hours,
minutes: x.minutes,
seconds: x.seconds
});
//save data
savingData.save();
} catch (e) {
console.log('malformed data');
}
}
})
});
});
});
我们正在使用try
and catch
来防止应用程序崩溃。 如果我们不使用它,并且JSON.parse
抛出错误的unexpected user input
错误,因为有时由于快速更改率而无法完全读取数据,则应用程序可能会崩溃。 我们想要避免的事情!
另外,请确保MongoDB服务器正在运行,否则应用程序将崩溃。
客户端代码
在本节中,我们将创建一个简单的静态HTML页面。 当通过socket.io接收到新数据时,我们将更新页面上显示的数据。 这些数据还可以用于创建实时图形和图表。
这是index.html
文件的简单代码:
<body ng-app="demo" ng-controller="demoController" ng-cloak class="ng-cloak">
<div>{{data.hours}} : {{data.minutes}} : {{data.seconds}}</div>
</body>
<script src="/path/to/angular.js"></script>
<script src='/path/to/socket.io.js'></script>
<script>
var socket = io.connect();
angular.module('demo', []).controller('demoController', ['$scope', function($scope) {
socket.on('updated', function(data) {
$scope.$apply(function(){
$scope.data = data;
});
});
}]);
</script>
ngCloak
指令用于防止AngularJS的模板在我们的应用程序加载时被浏览器以原始(未编译)形式短暂显示。
最后,我们需要添加以下CSS代码以使其工作,以防万一AngularJS在HTML正文之后加载。
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
display: none !important;
}
控制器以长函数形式编写,因此我们不需要注入参数。
每当接收到新数据时,我们都需要使用$scope.apply()
来更新视图上的数据。 $scope.apply()
接受一个函数或AngularJS表达式字符串,然后执行它。 然后,它会自动调用$scope.$digest()
来更新所有观察程序。 另一种选择是$timeout
(由AngularJS提供),类似于setTimeout
但默认情况下会自动将代码包装在$apply
。
运行应用程序
在启动Node.js服务器之前,我们需要确保MATLAB代码和MongoDB服务器正在运行。 要运行MongoDB服务器,您需要在终端上执行命令mongod
。 要运行Node.js服务器,必须在项目文件夹的根目录中执行命令node server.js
。
显示当前时间的静态页面将在127.0.0.1:3000
。
结论
在本文中,我们使用MEAN堆栈创建了一个Web应用程序,该应用程序从MATLAB程序获取JSON格式的数据。 借助JSONlab转换数据。 然后使用socket.io将数据发送到浏览器,从而实时反映浏览器上的更改。 该演示的完整源代码可在GitHub上找到 。
希望您喜欢这篇文章,并期待阅读您的评论。
From: https://www.sitepoint.com/creating-a-web-app-with-matlab-and-the-mean-stack/