使用MATLAB和MEAN Stack创建Web应用

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);
	});
});

与客户端建立连接并开始获取数据后,我们将执行两个操作:

  1. 使用socket.io的emit()函数将数据发送到浏览器
  2. 使用猫鼬中间件将数据保存在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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值