主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

用于 MATLAB 函数执行的 RESTful API

用于 MATLAB® 函数执行的 MATLAB Production Server™ RESTful API 使您能够使用 MATLAB 数据类型和协议缓冲区的 JSON 表示来评估远程服务器上的 MATLAB 函数。协议缓冲区支持仅在 Java® 和 .NET 客户端 API 中可用。

您可以使用基于 Web 的语言(例如 JavaScript®)编写使用 MATLAB Production Server RESTful API 的客户端代码,并将其嵌入 HTML 页面中。然后,您可以使用这些 Web 从 MATLAB Production Server 实例发送请求并检索响应。虽然基于 Web 可能更适合使用 JavaScript 编写的客户端代码,但您也可以使用任何 HTTP 支持的编程语言,如 Java、Python®、C++、.NET 等来开发客户端应用程序。

如果客户端程序从不同的域发出请求,使用 JavaScript 的程序员必须验证服务器上是否启用了跨域资源共享 (CORS)。要在服务器上启用 CORS,服务器管理员必须在 main_config 服务器配置文件中为 cors-allowed-origins 属性设置适当的值。

RESTful API 的特点

MATLAB 函数执行的 RESTful API 使用 HTTP 请求-响应模型与 MATLAB Production Server 进行通信。该模型包括请求方法、响应码、消息头、消息体。RESTful API 具有以下特点:

  • HTTP 方法(POST、GET 和 DELETE)构成了客户端和服务器之间通信的主要模式。

  • 唯一的统一资源标识符 (URI) 标识服务器创建的资源。

  • 消息头传达元数据,例如请求的 Content-Type

    • API 支持 application/json 作为 HTTP Content-Type 标头。

    • 用于 MATLAB 函数执行的 RESTful API 还仅通过 Java 和 .NET 客户端 API 支持 application/x-google-protobuf 作为 HTTP Content-Type

  • 请求的消息正文包含要发送到服务器的信息。

    • 如果使用 JSON 作为数据序列化格式,则已部署存档中包含的 MATLAB 函数的输入将以 JSON 表示并封装在消息正文中。有关详细信息,请参阅MATLAB 数据类型的 JSON 表示

    • 如果使用协议缓冲区 (protobuf) 进行数据序列化,Java 和 .NET 客户端库会提供帮助类,以根据 proto 格式内部创建 protobuf 消息并返回相应的字节数组。在请求的消息正文中使用该字节数组。

  • 响应的消息正文包含有关请求的信息,例如状态或结果。

    如果您使用 protobuf 进行数据序列化,Java 和 .NET 客户端库会提供方法和类来反序列化 protobuf 响应。

  • 该 API 支持服务器的同步和异步模式。

注意

下面的示例和图形使用 JSON 作为数据序列化格式。

同步执行

在同步模式下,客户端发出请求后,服务器的工作进程进程模块所有进一步的请求,直到完成对原始请求的处理为止。处理完成后,工作进程自动向客户端返回响应。由于在请求处理期间模块的是工作进程,如果有其他可用的工作进程,则服务器可以接受其他同步请求进行处理。要向服务器发出同步请求并等待响应,请使用POST Synchronous Request

下图说明了 RESTful API 在同步模式下的工作方式。

When the server receives a request in synchronous mode, it blocks all other requests till it finishes processing the current request.

示例:使用 RESTful API 和 JSON 同步执行幻方

此示例通过提供三个单独的实现(一个使用 MATLAB,一个使用 JavaScript ,一个使用 Python)展示了如何使用 RESTful API 和 JSON。执行此示例时,服务器将返回一个包含 25 个逗号分隔的值的列表。这些值是已部署的 MATLAB 函数 mymagic 的输出,以列主格式表示。myMagic 函数的 MATLAB 代码如下。

function out = myMagic(in)
out = magic(in);
end

为了运行此示例,需要运行包含已部署的 MATLAB 函数 myMagicMATLAB Production Server 实例。有关如何创建可部署存档的更多信息,请参阅针对 MATLAB Production Server 创建可部署存档。有关设置服务器的更多信息,请参阅使用命令行创建服务器实例

HTTP 请求

POST /ctfArchiveName/myMagic HTTP/1.1
Host: localhost:9910
Content-Type: application/json
Content-Length: 77

{"rhs":[4,1],"nargout":1, "outputFormat":{"mode":"small","nanType":"string"}}

使用 MATLAB 发出请求

在代码中,将 localhost 替换为您的主机名,将 ctfArchiveName 替换为您的可部署存档的名称,将 myMagic 替换为您的函数的名称。保存代码并在 MATLAB 中运行。服务器返回 myMagic 函数的输出。

url = 'http://localhost:9910/ctfArchiveName/myMagic';
payload = mps.json.encoderequest({[5]});
options = weboptions;
options.ContentType = 'text';
options.MediaType = 'application/json';
response = webwrite(url, payload, options);
result = mps.json.decoderesponse(response);
result{1}

使用 JavaScript 发出请求

您可以使用 JavaScript 运行 RESTful API 的此 Node.js® 实现。在代码中,将 localhost 替换为您的主机名,将 ctfArchiveName 替换为您的可部署存档的名称,将 myMagic 替换为您的函数的名称。将下面的代码保存为扩展名为 .js 的文件,并使用 Node.js 运行它。服务器返回 myMagic 函数的输出。

const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

const raw = JSON.stringify({
  "rhs": [4,1],
  "nargout": 1,
  "outputFormat": {"mode": "small","nanType": "string"}
});

const requestOptions = {method: "POST", headers: myHeaders, body: raw, redirect: "follow"};

fetch("http://localhost:9910/ctfArchiveName/myMagic", requestOptions)
  .then((response) => response.text())
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

使用 Python 发出请求

您可以在您选择的 Python 环境中运行以下代码。在代码中,将 URL 中的 CTF 存档和函数的名称更改为您的名称。默认情况下,存档名称为 ctfArchiveName,函数为 myMagic。该代码返回在服务器上运行的 myMagic 函数的输出。

import requests
import json

url = "http://localhost:9910/ctfArchiveName/myMagic"

payload = json.dumps({
  "rhs": [4,1],
  "nargout": 1,
  "outputFormat": {"mode": "small","nanType": "string"}
})
headers = {'Content-Type': 'application/json'}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

有关将 MATLAB 函数部署到 MATLAB Production Server 并使用 RESTful API 和 JSON 调用它的端到端工作流示例,请参阅 使用 RESTful API、JSON 和 JavaScript 创建基于 Web 的工具

异步执行

在异步模式下,客户端能够发布多个请求,并且在每种情况下,服务器都会通过创建新资源并返回与每个请求相对应的唯一 URI 来做出响应。URI 封装在响应消息的正文中。客户端可以使用服务器返回的 URI 进行查询和检索结果等用途。

异步模式的 RESTful API 调用如下表所列:

调用目的
POST Asynchronous Request

向服务器发出异步请求

GET Representation of Asynchronous Request

查看对服务器发出的异步请求的表示方式

GET Collection of Requests

查看请求集合

GET State Information

获取请求的状态信息

GET Result of Request

检索请求的结果

POST Cancel Request

取消请求

DELETE Request

删除请求

下图说明了 RESTful API 在异步模式下的工作方式。该图并未涵盖所有 RESTful API 调用。有关完整的调用列表,请参阅上表。

Asynchronous request processing

示例:使用 RESTful API 和 JSON 异步执行幻方

此示例展示如何使用 RESTful API 和 JSON 通过 JavaScript 进行异步执行。执行此示例时,服务器将返回一个包含 100 个逗号分隔的值的列表。这些值是已部署的 MATLAB 函数 myMagic 的输出,以列主格式表示。mymagic 函数的 MATLAB 代码如下。

function out = myMagic(in)
out = magic(in);
end

为了运行此示例,需要运行包含已部署的 MATLAB 函数 myMagicMATLAB Production Server 实例。有关如何创建可部署存档的更多信息,请参阅针对 MATLAB Production Server 创建可部署存档。有关设置服务器的更多信息,请参阅使用命令行创建服务器实例

示例 JavaScript 代码如下。

<!DOCTYPE html>
<html>
    <head>
        <title>Magic Square</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script>
            // MPS RESTful API (Asynchronous): Specify URL
            var hostname = "http://localhost:9910";
            var mode = "async";
            var clientID = "client100";
            var ctfName = "myMagic";
            var matlabFuncName = "myMagic"
            var url = hostname + "/" + ctfName + "/" + matlabFuncName + "?mode=" + mode + "&client=" + clientID;
            // Specify arguments
            var params = {
                "nargout": 1,
                "rhs": [100],
                "outputFormat": {"mode": "small"}
            };
            $.ajax(url, {
                data: JSON.stringify(params),
                //MPS RESTful API (Asynchronous): Specify Content-Type to application/json and Specify HTTP POST method
                contentType: 'application/json',
                method: 'POST',
                dataType: 'json',
                success: function(response) {
                    // Print Request URI to webpage
                    $("#requestURI").html('<strong>Request URI: </strong>' + hostname + response.self);
                    pollUsingUp(response);
                }
            });
            // Polling Server using UP
            function pollUsingUp(request) {
                setTimeout(function() {
                    var newSeq = parseInt(request.lastModifiedSeq) + 1;
                    var queryURI = hostname + request.up + "?since=" + newSeq + "&ids=" + request.id;
                    $.ajax({
                        url: queryURI,
                        method: 'GET',
                        dataType: 'json',
                        success: function(response) {
                            //Poll again if no data about the request was received.
                            if (response.data.length == 0) {
                                pollUsingUp(request);
                                return;
                            }

                            var requestResource = response.data[0];
                            // Print "state" of request
                            $("#state").html('<strong>State: </strong>' + requestResource.state);


                            if (requestResource.state != "READY" && requestResource.state != "ERROR") {
                                //Keep polling if the request is not done yet.
                                pollUsingUp(requestResource);
                            } else {
                                var requestURI = hostname + requestResource.self;
                                var responseURI = hostname + requestResource.self + "/result";
                                // Get result.
                                $.ajax({
                                    url: responseURI,
                                    // MPS RESTful API (Asynchronous): Specify HTTP GET method
                                    method: 'GET',
                                    dataType: 'json',
                                    success: function(response) {
                                        if (response.hasOwnProperty("lhs")) {
                                            $("#demo").html('<p>' +
                                                response.lhs[0] + '</p>');
                                            //Uncomment the next line if using JSON large representation
                                            //response.lhs[0].mwdata + '</p>');

                                        } else if (response.hasOwnProperty("error")) {
                                            alert("Error: " + response.error.message);
                                        }
                                        // MPS RESTful API (Asynchronous): Specify HTTP DELETE method
                                        $.ajax({
                                            url: requestURI,
                                            method: 'DELETE'
                                        });
                                    }
                                });
                            }
                        }
                    });
                }, 200);
            }
        </script>
    </head>
    <body>
        <p><strong>MPS RESTful API and JSON EXAMPLE</strong></p>
        <p> >> myMagic(5)</p>
        <p id="requestURI"></p>
        <p id="state"></p>
        <p id="demo"></p>
        <p> # output from server returned in column-major format </p>
    </body>
</html>

管理 HTTP Cookie

Azure® 上的 MATLAB Production Server 部署提供了一个 HTTPS 端点 URL 来调用部署到服务器的 MATLAB 函数。Azure 应用程序网关提供基于 cookie 的会话亲和性,它使用 cookie 将用户会话保留在同一台服务器上。在接收到来自客户端程序的请求后,应用程序网关会将 Set-Cookie HTTP 响应标头设置为有关处理该请求的服务器虚拟机 (VM) 的信息。

异步请求执行

使用异步请求执行部署到服务器的 MATLAB 函数的客户端程序必须将所有后续请求的 Cookie HTTP 请求标头设置为 Set-Cookie 标头的值。这可确保处理第一个请求的同一服务器虚拟机处理该会话的所有后续请求。

同步请求执行

使用同步请求执行部署到服务器的 MATLAB 函数的客户端程序不得将 Cookie HTTP 请求标头设置为 Set-Cookie 标头的值,并且必须清除 Cookie 标头的值(如果之前已设置)。这可以确保同步请求的负载平衡,并且同一台服务器虚拟机不会处理它们。

另请参阅

主题