Matlab Mex Socket Wrapper Library

MATLAB Mex Socket Wrapper Library

If you want to work with sockets, you have two options:

1) use Java capabilities from inside MATLAB (see this answer here on SO for a quick example):

  • TCP/IP Socket Communications in MATLAB
  • TCP/IP Socket Communications in MATLAB using Java Classes

2) use C MEX-wrappers:

  • msocket
  • TCP/UDP/IP Toolbox

I also think that the Instrument Control Toolbox includes support for TCP UDP communication.

Using boost in MATLAB MEX library, different from MATLAB's version

One solution is to change the way matlab opens your plugin, by writing a small loader mex file which itself has no dependency on boost, call it foo.mexglx

It's mexFunction call simply does this

void mexFunction (int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[])
{
gMexEntry (nlhs, plhs, nrhs, prhs);
}

where the gMexEntry variable is a function pointer declared as

typedef void (*entryfunc_t)(int, mxArray**, int, const mxArray**);
entryfunc_t gMexEntry;

and populated by a static constructor when the module is loaded (all error checking ignored for brevity).

fh = dlopen ('bar.mexglx', RTLD_NOW | RTLD_DEEPBIND );
void * p = dlsym (fh, "mexFunction");
gMexEntry = reinterpret_cast<entryfunc_t> (p);

The chain of events is that when Matlab calls your function, the thin wrapper with no boost dependency will open your function with the boost dependency using the RTLD_DEEPBIND option of dlopen, which will place the lookup scope of the symbols in this library (using your version of boost) ahead of the global scope (using Matlab's old boost). Then the actual mexFunction call will forward to bar.

If you do your cmdline linking correctly, using 'ldd' you should see that 'foo.mexglx' has no dependency on boost, and 'bar.mexglx' has all your usual dependencies.

I've been using this technique heavily for months with no obvious signs of failure. I do still have some slight concerns that something I don't understand might go wrong, but for the time being this is the only solution I've got (other than writing a full out-of-process execution engine replicating the mxArray interface and communicating with pipes, or linking everything statically which isn't practical for my situation)

Socket communication between server app and Matlab client using Java

There's at least two separate issues here. One is how to structure Matlab code that speaks a protocol like this. The other his how to represent possibly complex data in this wire protocol you have.

As far as organizing the Matlab code, you could use a class to organize the message in a more structured manner, and use typecast to convert the numbers down to bytes. Maybe something like this. This assumes your client and server have the same native representation of primitive types, and ignores network byte ordering (htonl/ntohl).

classdef learnvst_message
%//LEARNVST_MESSAGE Message for learnvst's example problem
%
% Examples:
% msg = learnvst_message;
% msg.payload = { 'Hello world', 1:100 }
% msg.payloadType = uint8([ 5 12 0 0 ]); % guessing on this

properties
magicNumber = uint32(445566);
payloadType = zeros(4, 1, 'uint8'); %// header B
payload = {};
end

methods
function out = convertPayload(obj)
%//CONVERTPAYLOAD Converts payload to a single array of bytes
byteChunks = cellfun(@convertPayloadElement, obj.payload, 'UniformOutput',false);
out = cat(2, byteChunks{:});
end

function out = marshall(obj)
payloadBytes = convertPayload(obj);
messageSize = uint32(4 + numel(payloadBytes)); %// ex first 8 bytes
out.headerBytes = [
typecast(obj.magicNumber, 'uint8') ...
obj.payloadType ...
typecast(messageSize, 'uint8')];
out.payloadBytes = payloadBytes;
end

function sendTo(obj, host, port)
m = marshall(obj);
mySocket = Socket(host, port);
d_output = mySocket.getOutputStream();
d_output.write(m.headerBytes, 0, numel(m.headerBytes));
d_output.write(m.messageBytes, 0, numel(m.messageBytes));
mySocket.close();
end

end
end

function out = convertPayloadElement(x)
if isnumeric(x)
out = typecast(x, 'uint8');
elseif ischar(x)
% Assumes receiver likes 16-bit Unicode chars
out = typecast(uint16(x), 'uint8');
else
% ... fill in other types here ...
% or define a payload_element class that marshalls itself and call
% it polymorphically
error('Unsupported payload element type: %s', class(x));
end
end

More readable, I think, and a bit less code smell. As a caller, you can work with the data in a more structured form, and it encapsulates the conversion to the wire-protocol bytes inside the class's marshalling method. That "convertPayload" is what "stitches together a generic block of memory together made of many different data types". In Matlab, a uint8 array is a way to append representations of different data types together in a continguous block of memory. It's basically a wrapper around an unsigned char [], with automatic reallocation. And typecast(...,'uint8') is sort of the equivalent of doing a reinterpret cast to char * in C/C++. See the help for both of them.

But this brings up more questions. How does the server know how long each of the components of the payload are, what their shape is if multidimensional, and what their respective types are? Or what if they're complex data types - could they nest? You might need to embed little headers inside each of the payload elements. The code above assumes the 4-byte payload type header fully describes the payload contents.

Sounds like what you're looking for may be a sort of self-describing format for heterogeneous array based data. There are existing formats for that, including NetCDF, HDF5, and Matlab's own MAT files. Matlab has built-in support for them, or you could pull in third-party Java libraries for them.

As far as speed - You're going to have to pay each time you pass data across the Matlab/Java boundary. Large primitive arrays are relatively cheap to convert, so you probably want to pack most of the message up in a byte array in Matlab before passing it to Java, instead of making lots of separate write() calls. It'll depend in practice on how big and complex your data is. See Is MATLAB OOP slow or am I doing something wrong? for a rough idea of the cost of some Matlab operations, including Java calls. (Full disclosure: that's a self-plug.)

How can I run MATLAB code for isolated spoken words recognition from PHP?

You have a few options here:

  • If MATLAB installed on the server where the PHP application would be deployed (not your current development environment), you can invoke it directly just like any other program (matlab -r "...") using whatever is the equivalent of EXECUTE command in PHP. Here are some resources (make sure to also checkout the linked questions as well):

    • How to call MATLAB from command-line and print to stdout before exiting
    • Running a cmd file without GUI popping up
    • Pass Parameters _ Shell Script - Octave Script

    Others have commented on how to pass input/output between PHP and your MATLAB script. For example, you could design your MATLAB function to receive the path of WAV file as input, process it and save any resulting image to disk:

    function myFunc(filename)
    [y,Fs] = audioread(filename);
    img = my_process_func(y, FS);
    imwrite(img, 'out.png');
    end

    Which is invoked from PHP as:

    % Of course you have to make sure "myFunc" is available on the MATLAB path.
    % Think: "addpath(..)" or just "cd(..)" into the directory first
    matlab -wait -nodisplay -r "myFunc('audio.wav'); quit;"

    You could then read the output image in the PHP application.

  • If not, what deployment-related toolboxes do you have available? MATLAB Compiler and related toolboxes like MATLAB Builder NE and MATLAB Builder JA.

    Those will compile your program into an executable/.NET Assembly/JAR file respectively, and all of them require the freely available MCR Runtime to be installed. In other words, the executables do not need to have a full MATLAB installation on the target machine, only the MCR runtime.

    You would run the executable in the same manner as before.

    Another product is the MATLAB Coder, which converts your MATLAB code into C++ program. When compiled, it can run without any external requirement.

    A new product by MathWorks is MATLAB Production Server. Personally I know nothing about it :)

  • Yet another option is to use TCP/IP to communicate between PHP and MATLAB. A server would be run on the MATLAB side, using socket programming written as C MEX-file or a Java class. See:

    • MATLAB Mex Socket Wrapper Library
    • Writing Java's pw.println(), etc. in MATLAB

    The client being your PHP application. The idea is to have MATLAB listening for connections, reading whatever input is given by a client, eval it, and return the result. This is more involved than the other options, as you have to deal with serialization and other things like concurrency. The advantage is that MATLAB can be run on a separate server, even on multiple servers on the cloud (see this post).

So first, decide what approach best suits your project, then it would be easier to answer specific questions... Just always consult the documentation first, MATLAB toolboxes are very well documented and usually include many examples. Here are a couple more resources specific to MATLAB Compiler products family:

  • Webinar: Application Deployment with MATLAB
  • PDF File: MATLAB Application Deployment - Web Example Guide

Note that they concentrate on ASP.NET and Java JSP/servlet applications. In your case, the PHP application would communicate with a middle tier running a web service built using one of the above two options (or simply design a CGI-like site running plain executables built using the MATLAB Compiler as explained earlier).



Related Topics



Leave a reply



Submit