Struct Support for RESTful Requests Using Protocol Buffers in .NET Client
This example shows how to send MATLAB® structures (struct (MATLAB)) represented as arrays of .NET objects as input
when you make a synchronous request using the .NET client API, MATLAB
Production Server™
RESTful API for MATLAB Function Execution, and protocol buffers (protobuf). The example
provides and explains a sample Java® client, SortStudentsSyncREST.cs, for evaluating a
MATLAB function deployed on the server.
To use protobuf when making a request to the server, set the
HTTP Content-Type request header to
application/x-google-protobuf in the client code. The
MathWorks.MATLAB.ProductionServer.Client.REST namespace in the .NET
client library provides helper classes to internally create protobuf messages based on a proto
format and returns the corresponding byte array. Use this byte array in the HTTP request body.
The .NET client library provides methods and classes to deserialize the protobuf
responses.
In synchronous request execution, after a client posts a request, the server blocks all further requests until it has completed processing the original request. After processing is complete, the server automatically returns a response to the client. For more information, see Synchronous Execution.
To use the .NET client API, you must add a reference to the MathWorks.MATLAB.ProductionServer.Client.dll file in your C# project. For more information on preparing your Microsoft®
Visual Studio® environment for your project, see Prepare Your Microsoft Visual Studio Environment.
In an on-premises MATLAB
Production Server installation, the client APIs are located in
, where
$MPS_INSTALL/client is the MATLAB
Production Server installation location. The client APIs are also available for download at MATLAB Production Server Client Libraries. The Java client API is also hosted in a Maven™ repository at https://mvnrepository.com/artifact/com.mathworks.prodserver/mps_java_client.$MPS_INSTALL
Deploy MATLAB function to server
Write a MATLAB function sortstudents that takes an array of
structures containing student information as input and returns a sorted array of
students based on their score. Student name, score and grade form the fields of the
input structure. Deploy this function on the server. The example assumes that the
server instance is running at http://localhost:9910.
For information on how to deploy, see Create Deployable Archive for MATLAB Production Server.
Code for a sample MATLAB
struct
S and the MATLAB function sortstudents follows.
S.name = 'Ed Plum'; S.score = 83; S.grade = 'B+'
function sorted = sortstudents(unsorted)
scores = {unsorted.score};
scores = cell2mat(scores);
[s i] = sort(scores);
sorted = unsorted(i);Create helper classes
Create .NET classes to marshal data to and from the MATLAB
struct.
Create a .NET class
Studentwith the same data members as the input structure.class Student { public string name; private string gr; private int sc; public string grade { get { return gr; } set { gr = value; } } public int score { get { return sc; } set { sc = value; } } public override string ToString() { return name + " : " + grade + " : " + score; } }Create a .NET class
StudentMarshallerthat extends the interfaceMWDefaultMarshalingRules. Since .NET does not natively support structs, extending theMWDefaultMarshalingRulesinterface lets you implement a new set of marshaling rules for the list of classes being marshaled, serialize .NET objects to structs and deserialize structs to .NET objects. Set theStructTypesproperty to return the typeStudent.class StudentMarshaler : MWDefaultMarshalingRules { public override IList<Type> StructTypes { get { return new List<Type> { typeof(Student) }; } } }Create an array of type
Studentthat you want to sort.Student s1 = new Student(); s1.name = "Tony Miller"; s1.score = 90; s1.grade = "A"; Student s2 = new Student(); s2.name = "Ed Plum"; s2.score = 80; s2.grade = "B+"; Student s3 = new Student(); s3.name = "Mark Jones"; s3.score = 85; s3.grade = "A-"; Student[] unsorted = new Student[] { s1, s2, s3 };
Make Synchronous Request to Server
In the C# client code, use the POST Synchronous Request to make the initial request to the server. For more information about synchronous request execution in MATLAB Production Server, see Synchronous Execution.
Create the request.
Create a POST Synchronous Request using the .NET
WebRequest.Createmethod.The request URL comprises the address of the server instance (
http://localhost:9910), the name of the deployed archive (sortstudents), and the name of the MATLAB function to evaluate (sortstudents). Set the HTTP request method toPOST. Set the HTTPContent-Typerequest header toapplication/x-google-protobuf, as the API returns a byte array of protocol buffer messages.String mpsBaseUrl = "http://localhost:9910"; var firstRequest = (HttpWebRequest)WebRequest.Create(mpsBaseUrl + "/sortstudents/sortstudents"); firstRequest.Method = "POST"; firstRequest.ContentType = "application/x-google-protobuf";
Send the request to the server.
Send the request to the server using the .NET
WebRequest.getResponsemethod.Use the
Create(arg1, arg2, arg3, arg4)method defined in theMATLABParamsclass of the MATLAB Production Server .NET client API to build the protocol buffer message. TheCreatemethod takes as input the expected number of output arguments for the deployed function, the expected output type, an object of typeMWDefaultMarshalingRules, and an array of objects representing the inputs to the deployed function. Since the deployedsortstudentsfunction returns a single array of structs, setarg1to1andarg2tonew List<Type> { typeof(Student[]) }. Setarg3tonew StudentMarshaler(), andarg4tonew object[] { unsorted }, which is the input to thesortstudentsfunction.MATLABParams mlParams = MATLABParams.Create(1, new List<Type> { typeof(Student[]) }, new StudentMarshaler(), new object[] { unsorted }); mlParams.WriteTo(firstRequest.GetRequestStream()); var response = (HttpWebResponse)firstRequest.GetResponse();
For more information on the WebRequest class, see Microsoft documentation.
Receive and Interpret Server Response
On successful execution of the POST Synchronous Request, the server responds with
a protocol buffer message. Parse the protocol buffer message using methods from the
MATLABResult class to get the result of the request. To
create a MATLABResult object, pass the
MATLABParams
mlParams object and the response body of the POST Synchronous
Request to the Create method. Set the return type of the
MATLABResult
mlResult to Student[].
If an error occurs when the deployed MATLAB function executes, the call to the Result method
throws a MATLABException that contains the error message from
MATLAB.
MATLABResult mlResult;
mlResult = MATLABResult.Create(mlParams, response.GetResponseStream());
try
{
Student[] result = mlResult.Result<Student[]>();
Console.WriteLine("Printing the sorted Student array...\n");
PrintStudent(result);
}
catch (MATLABException e)
{
Console.WriteLine(e.ToString());
}The example uses a helper method PrintStudent that takes as
input the response body of the POST Synchronous Request and prints the
corresponding sorted list of
students.
static void PrintStudent(Student[] students)
{
foreach (Student s in students)
{
Console.WriteLine(s.ToString());
}
}Running the application generates the following output.
Printing the sorted Student array... Ed Plum : B+ : 80 Mark Jones : A- : 85 Tony Miller : A : 90
Sample code for the SortStudentsSyncREST.cs C# client
follows.
Code:
