File Exchange

image thumbnail

jebej/MatlabWebSock​et

version 1.4.0.0 (125 KB) by Jeremy
A simple WebSocket library for Matlab.

15 Downloads

Updated 20 Nov 2017

GitHub view license on GitHub

MatlabWebSocket is a simple library consisting of a websocket server and client for MATLAB built on Java-WebSocket, a java implementation of the websocket protocol. Encryption is supported with self-signed certificates made with the java keytool.
Please see the documentation on Github:
https://github.com/jebej/MatlabWebSocket

Comments and Ratings (32)

MB Sylvest

This is a great piece of code. I can make the wss and ws work over LAN but for some reason it does not seem to work over the internet. I have forwarded the port on the router. Is there anything else that needs to be done to make it work over internet? do I need to run a http server simultanously or how can I setup the matlab websocket server properly? Any advise is highly appreciated.

mavillar

Works like a charm!!!!!!

Thanks a lot Jeremy...... really simple and powerful!

Rongzong Wu

Excellent work Jeremy! The code runs great!

Did anyone solve the:
'Undefined function or variable 'MatlabWebSocketSSLClient'.'
problem?
Nothing works for me...

This is so frustrating... so if problem is type of data pass to java which is double 1x1 I try change java code to:
public MatlabWebSocketServer( double[] port ) {
super( new InetSocketAddress( port[0] ) );
}
offcourse with no luck so back to your code if I add uri = handle(java.net.URI(obj.Port)); and:
No constructor 'java.net.URI' with matching signature found.
so I try whitch java -all
D:\Matlab\toolbox\matlab\general\java.m
java is a built-in method % matlab.ui.Figure method
java is a built-in method % matlab.ui.Root method
java is a built-in method % matlab.ui.control.Component method
java is a built-in method % matlab.ui.container.Container method
java is a built-in method % matlab.ui.container.CanvasContainer method
java is a built-in method % matlab.ui.control.WebComponent method
java is a built-in method % matlab.graphics.internal.GraphicsJavaVisible method
java is a built-in method % JavaVisible method
java is a built-in method % audiovideo.mmreader method
java is a built-in method % schema.method method
java is a built-in method % schema.class method
java is a built-in method % handle.handle method
java is a built-in method % matlab.graphics.internal.PlotManager method
java is a built-in method % javahandle.com.mathworks.hg.peer.Echo method

and:
>> which java.net
'java.net' not found.

any hint?

Jeremy

Simon, I'll try to look into this next week.

Manuel Dias

Ok quick update. When i created a EchoServer i didn't pass the port like an integer, but as ha array of character like this: ('ws://localhost:3000') and this isn't correct! I undo my last changes and tried EchoServer(3000); and it worked perfectly and i runned the runtest function and it worked perfectly. Milan if you are having any troubles double check everything, like java path and even the addon path, you must add everything to the matlab prefdir. Hope this helps

Manuel Dias

On the WebSocketServer there is a bug too like Milan said and as i stumbled upon. The problem is there is no constructor that has MatlabWebSocketServer(obj.Port). I mean there is but the type of data is different. In MatlabWebSocketServer it as an integer as input parameter and obj.Port is a character array so you have to change this like so:

uri = handle(java.net.URI(obj.Port));
obj.ServerObj = handle(MatlabWebSocketServer(uri.port),'CallbackProperties');

This worked for me... It seems that the code has some bugs but with this i think it should work just fine

I have simmilar problem like Manuel Dias

ser = EchoServer(30000)
obj.ServerObj = handle(MatlabWebSocketServer(obj.Port),'CallbackProperties');
Undefined function or variable 'MatlabWebSocketServer'.

Error in WebSocketServer/start (line 70)
obj.ServerObj = handle(MatlabWebSocketServer(obj.Port),'CallbackProperties');

Error in WebSocketServer (line 43)
obj.start();

I change WebSocketServer.m line 69 to:

import io.github.jebej.matlabwebsocket.*;
obj.ServerObj = handle(MatlabWebSocketServer(obj.Port),'CallbackProperties');

But still same result

Manuel Dias

There is 2 bugs in this library!
First if you try this at first you might get an error from import that is lacking the characters '.*' at the final of the path of import... Just add those 2 characters at the end of the path in every import!

Secondly if you add the characters it will appear another error undefined function or variable. This is because the import works like it is on Java. If you read the import sentence carefully you are import the function.* and that doesn't make any sense. You only have to delete the function name, like this : import io.github.jebej.matlabwebsocket.*; and you are done. This example was from the WebSocketClient.m file. You can do this on the Server as well and you are good to go!! Hope it helps

Manuel Dias

Hi Jeremy i am having a problem. Doing everything on the README file and restarting MatLab i am getting this error:

>> client=SimpleClient('ws://localhost:8080/');
Undefined function or variable 'MatlabWebSocketClient'.

Error in WebSocketClient/open (line 70)
obj.ClientObj = handle(MatlabWebSocketClient(uri),'CallbackProperties');

Error in WebSocketClient (line 45)
obj.open();

Error in SimpleClient (line 11)
obj@WebSocketClient(varargin{:});

Any ideas how to solve this?

Well done for the great piece of work.

Excuse the rather basic question (I'm a newbie) but where/how are responses captured on the client side?
Thank you

Hi Jeremy,
I've really enjoyed using your library while working on my project during the last couple of months!!!

And I'm contacting you again, since I believe to have found one small issue:

While deleting the WebSocket client object by executing ("delete(myClient)") it happens often, that another onMessage event has been fired off during the closing process, leading to an exception with en error message:
_______
Invalid or deleted object.

Error in LDClient/onBinaryMessage (line 339)
if obj.Debug

Error in WebSocketClient/binaryMessageCallback (line 132)
obj.onBinaryMessage(e.blob.array);

Error in WebSocketClient>@(varargin)obj.binaryMessageCallback(varargin{:}) (line 75)
set(obj.ClientObj,'BinaryMessageCallback',@obj.binaryMessageCallback);
______

It looks like the client object (i.e. obj) does not exist anymore at the time the binaryMessageCallback (belonging to that object) is still being executed?

It really looks like a timing issue, since it doesn't happen always. (My WebSocket messages are being sent approximately each quarter of a second).

In WebSocketClient.m I found

function close(obj)
% Close the websocket connection and explicitely delete the
% java client object
if ~obj.Status; warning('Connection is already closed!');return; end
obj.ClientObj.closeBlocking()
delete(obj.ClientObj);
obj.ClientObj = [];
end

Is "CloseBlocking" there to prevent such issues? What it does exactly is "hidden" in the jar file, I guess...

Can you please comment on that? Do I do something wrong?

Thank you!

Simon

Thanks!!!

Jeremy

By default java bytearrays are converted to MATLAB int8 arrays, and so some special characters will map to negative values, e.g. typecast(uint8('ö'),'int8') = -10. To convert back to char, you need to convert the int8 array to uint8 (unsigned/positive values). E.g., if your bytearray is A, do char(typecast(A,'uint8')). See https://www.mathworks.com/help/matlab/ref/typecast.html.

Hi Jeremy, that's awesome! The content of fragmented messages come now over intact. Thank you so much for you quick response!!!

I've had another not so critical remark: if special characters are part of the transmitted WebSocket package (like ä, ö,... - German stuff ;-)) - the bytearray parameter of the onBinaryMessage function contains negative values for these characters and obviously converting in characters - char(bytearray) - doesn't work properly either.

Is this also a Matlab wrapper issue or something deeper in the java library?

Simon

Peter Cove

Great library!

Jeremy

Hey Simon, can you try the latest release and let me now if it works? You shouldn't need to change your code, just update the JAR file, and the onMessage method should now properly execute when all the fragments are received.

That's great! Thank you Jeremy!

Jeremy

Hi Simon, thanks for the details. Yes you're right, the message fragments methods have not been wrapped, but it should be fairly easy to do. I've opened an issue and I'll get to it as soon as possible (https://github.com/jebej/MatlabWebSocket/issues/6). You can expect a new release next week.

Hi again,

Not being very good neither in java nor in Matlab, I nevertheless tried to take a look into the library code...

In the java library I see in the "WebSocketClient.class" 3 functions, related with receiving messages:

public final void onWebsocketMessage(WebSocket conn, String message)
{ onMessage(message); }

public final void onWebsocketMessage(WebSocket conn, ByteBuffer blob)
{ onMessage(blob); }

public void onWebsocketMessageFragment(WebSocket conn, Framedata frame)
{ onFragment(frame); }

The latter one seems to handle with WebSocket messages, that might be fragmented.

On the other side I see in the "MatlabWebSocketClient.class" only 2 functions

public void onMessage(String message)
{ ... }

public void onMessage(ByteBuffer blob)
{ ... }

Can it be, that the "Web Socket Fragments" are not implemented in the Matlab part of the library?

Thanks again for your help!

Simon

Thank you Jeremy for you prompt reply!

Increasing the Java heap size didn't solve the problem unfortunately. It is not so much about the size of the WebSocket frames but the fact, that my WebSocket server (a piece of hardware which I can't influence much) splits JSON strings and packs them into two or more continuous frames from a given data payload size (way below 1Mb though!).

And those split messages don't come over to the Matlab part of the WebSocket client at all. I suspect they are not correctly treated in the Java part of the WebSocket library.

Simon

Thank you Jeremy for you prompt reply!

Increasing the Java heap size didn't solve the problem unfortunately. It is not so much about the size of the WebSocket frames but the fact, that my WebSocket server (a piece of hardware which I can't influence much) splits JSON strings and packs them into two or more continuous frames from a given data payload size (way below 1Mb though!).

And those split messages don't come over to the Matlab part of the WebSocket client at all. I suspect they are not correctly treated in the Java part of the WebSocket library.

Simon

Jeremy

Hey Simon, try increasing the Java heap size (in MATLAB) to something at least ~300MB bigger than the data you are trying to transfer.

Hi Jeremy,

I've been using your very good WebSocket library to make Matlab (2017b) as a WebSocket client communicate with a WebSocket Server.

It seems that I have an issue with the composed WebSocket messages (the FIN bit for marking the final message and the OPCODE bits for marking the continuation frame):
- My WebSocketServer is sometimes sending larger amount of binary data in several continuous WebSocket frames. In such a case the bytearray simply "doesn't come over" in Matlab, as the underlying java library couldn't handle such cases.

I'm almost sure the it muss happen in the "java part" (matlab-websocket-1.3.jar), that I cannot debug, since I "see" the sent data by using Wireshark.

Thanks for your help!

Simon

Jeremy

Hey agatte, can you try the latest release?

agatte

Hi Jeremy,

I have still one bug in closing.

x=fxaMatWebSocketClient('ws://v.....rs.mt:8000/ws');

x.close();
Struct contents reference from a non-struct array object.

Error in matWebSocketClient/close (line 75)
obj.client.close()

Error in matWebSocketClient/close_callback (line 150)
obj.close();

Error in matWebSocketClient>@(h,e)obj.close_callback(h,e) (line 63)
set(obj.client,'OnCloseCallback',@(h,e) obj.close_callback(h,e));

agatte

Hello Jeremy,
I am trying to test your code.
I can't run it properly. I just test example :
echoServer and I obtain an error :

Error using javaObject
No class org.java_websocket.matlabbridge.MatlabWebSocketServerBridge can be located on the Java class path

Error in matWebSocketServer (line 27)
javaObj = javaObject('org.java_websocket.matlabbridge.MatlabWebSocketServerBridge',port);

Error in echoServer (line 11)
obj@matWebSocketServer(port);

Error in testWebSocket (line 8)
test = echoServer('30000');
Do You have any idea ?

Jeremy

Hey Ed, I just fixed this problem in the new version, only one file was changed:

matWebSocketClient.m

You can download the new version here and simply replace the old one:

https://github.com/jebej/MatlabWebSocket/blob/master/matlab/matWebSocketClient.m

Ed Nieters

This code works very nicely and has saved me quite a bit of time.

I get an error on close of the client and am unclear if the bug is mine or in matWebSocketClient.m.

My code (classdef fooClient < matWebSocketClient) lets me successfully create a variable and do a send to your echoServer.

If I do a close, I get an error.

x=fooClient('ws://localhost:30000');
x.close

calls my onClose() function in fooClient and then generates this:

Attempt to reference field of non-structure array.
Error in matWebSocketClient/close (line 66)
obj.client.close()
Error in matWebSocketClient/close_callback (line 143)
obj.close();
Error in matWebSocketClient>@(h,e)obj.close_callback(h,e) (line 58)
set(obj.client, 'OnCloseCallback', @(h,e) obj.close_callback(h,e));

Any thoughts?
Thanks.

--Ed

Jeremy

Julien, sorry I took so long to answer.

Unfortunately, this is a known issue that is probably caused by the underlying Java library used for websockets and I cannot fix it as I do not know java well enough.

Another user has reported (https://github.com/jeremy-y12/MatlabWebSocket/issues/1) that this error does not occur on Unix (probably Linux too) so if you have the possibility of changing your OS that would be a work around.

Thank you for this code.

However, I have a small error when deleting a server. I can create an echoServer, deleting it seems to partially work (the client displays "websocket closed"), but when I want to create a new instance of an echoServer I get a Java error. Then, if I want to create a new instance of an echoServer on another port, this is OK.

Here is a short example:

>> test=echoServer(30000)

test =

echoServer with properties:

server: [1x1 javahandle_withcallbacks.org.java_websocket.matlabbridge.MatlabWebSocketServerBridge]
status: 1
connections: []
log: []

>> test.delete()
>> clear
>> test2=echoServer(30000)

test2 =

echoServer with properties:

server: [1x1 javahandle_withcallbacks.org.java_websocket.matlabbridge.MatlabWebSocketServerBridge]
status: 1
connections: []
log: []

Exception in thread "WebsocketSelector333" java.lang.NullPointerException
at org.java_websocket.matlabbridge.MatlabWebSocketServerBridge.onError(MatlabWebSocketServerBridge.java:107)
at org.java_websocket.server.WebSocketServer.handleFatal(WebSocketServer.java:462)
at org.java_websocket.server.WebSocketServer.run(WebSocketServer.java:290)
at java.lang.Thread.run(Unknown Source)

>> test3=echoServer(30000)

test3 =

echoServer with properties:

server: [1x1 javahandle_withcallbacks.org.java_websocket.matlabbridge.MatlabWebSocketServerBridge]
status: 1
connections: []
log: []

Any idea?

I'm using Matlab 2015b.

Thank you in advance.

Updates

1.4.0.0

- onMessage methods now receive fragmented messages (they are first collated)

1.2.0.0

- The MATLAB central version is at 1.2, which corresponds to the 1.0 release on Github (will fix this).
- The server is now be able to be closed and restarted on the same port
- WebSocketSecure (wss) is now supported via self-signed certificates

1.1.0.0

Added a client, renamed the JAR to be more general. Make sure you update the names in the java class path and in your m files!
Also wrapped the java objects in handles to avoid possible memory leaks.

MATLAB Release Compatibility
Created with R2014b
Compatible with any release
Platform Compatibility
Windows macOS Linux