chilipeppr / serial-port-json-server

Serial Port JSON Server is a websocket server for your serial devices. It compiles to a binary for Windows, Mac, Linux, Raspberry Pi, or BeagleBone Black that lets you communicate with your serial port from a web application. This enables web apps to be written that can communicate with your local serial device such as an Arduino, CNC controller, or any device that communicates over the serial port.
http://chilipeppr.com
GNU General Public License v2.0
322 stars 101 forks source link

Garbage chars when reconnecting without disconnecting first #50

Open ghost opened 6 years ago

ghost commented 6 years ago

It seems that if clients (or even the same client) reconnect without disconnect first, they will receive garbage chars. For example in an html page I have a "Connect" button:

  1. load the page
  2. press connect
  3. open the port and all is fine
  4. reload the page, without disconnect first
  5. try to connect again - ok
  6. open the port - ok
  7. now the received data is wrong, with all the chars shuffled

To get the things back to work I have to restart the serial-port-json-server.

It's a known behavior? Is there a way to avoid this? I'm interested in only one client at time, so it would be fine to forcefully disconnect any client before accept a new connection.

My page is a front-end to spjs in order to test some serial devices connected to my RPi3 (Raspbian Lite) and the baudrate is always the same.

When I say "garbage" chars I don't actually mean wrong or non-readable ones, but they are "messed up". I apologize I cannot describe it better in English. An example, if the expected answer is:

$CUBBY,VER,01.00*21

reloading the page (steps 4..7) I receive the following:

$CUBBY,V*21
ER,01.00$CUBBY,V*21

and similar. Right now I'm not able to provide a live preview of my snippet (I can do in the following days if needed) but here some functions of my code:

var open = function(address) {
    var url = address;
    ws = new WebSocket(url);
    ws.onopen = onOpen;
    ws.onclose = onClose;
    ws.onmessage = onMessage;
    ws.onerror = onError;
};

var onMessage = function(event) {
    var data = event.data;

    try {
        var json = JSON.parse(data);
        if (json.hasOwnProperty("SerialPorts")) {
            for (var i = 0; i < json["SerialPorts"].length; i++) {
                var item = json["SerialPorts"][i];
                $("#cboPort").append("<option value=" + item["Name"] + ">" + item["Name"] + "</option>");
            }

        } else if (!json.hasOwnProperty("Cmd") && json.hasOwnProperty("D")) {
            var msg = json["D"];            
            addMessage(msg.slice(0, -1), "recv");
        }
    } catch(e) {
    }
};
chilipeppr commented 6 years ago

I would test to see if you can reproduce that behavior in this workspace. http://chilipeppr.com/serialport

If you can, then that at least eliminates something in your code.

On Sat, May 5, 2018 at 11:54 AM, Mark-81 notifications@github.com wrote:

It seems that if clients (or even the same client) reconnect without disconnect first, they will receive garbage chars. For example in an html page I have a "Connect" button:

  1. load the page
  2. press connect
  3. open the port and all is fine
  4. reload the page, without disconnect first
  5. try to connect again - ok
  6. open the port - ok
  7. now the received data is wrong, with all the chars shuffled

To get the things back to work I have to restart the serial-port-json-server.

It's a known behavior? Is there a way to avoid this? I'm interested in only one client at time, so it would be fine to forcefully disconnect any client before accept a new connection.

My page is a front-end to spjs in order to test some serial devices connected to my RPi3 (Raspbian Lite) and the baudrate is always the same.

When I say "garbage" chars I don't actually mean wrong or non-readable ones, but they are "messed up". I apologize I cannot describe it better in English. An example, if the expected answer is:

$CUBBY,VER,01.00

reloading the page (steps 4..7) I receive the following:

$CUBBY,V21 ER,01.00$CUBBY,V21

and similar. Right now I'm not able to provide a live preview of my snippet (I can do in the following days if needed) but here some functions of my code:

var open = function(address) { var url = address; ws = new WebSocket(url); ws.onopen = onOpen; ws.onclose = onClose; ws.onmessage = onMessage; ws.onerror = onError; };

var onMessage = function(event) { var data = event.data;

try { var json = JSON.parse(data); if (json.hasOwnProperty("SerialPorts")) { for (var i = 0; i < json["SerialPorts"].length; i++) { var item = json["SerialPorts"][i]; $("#cboPort").append("<option value=" + item["Name"] + ">" + item["Name"] + ""); }

  } else if (!json.hasOwnProperty("Cmd") && json.hasOwnProperty("D")) {
      var msg = json["D"];            
      addMessage(msg.slice(0, -1), "recv");
  }

} catch(e) { } };

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/chilipeppr/serial-port-json-server/issues/50, or mute the thread https://github.com/notifications/unsubscribe-auth/AHidbX917-bOnLyH2wXAlnMg7aML6xNoks5tvfVygaJpZM4TzwDS .

ghost commented 6 years ago

Well, with your environment the behavior is different. Here what happens with my system:

  1. connect to the host and open the serial port
  2. receive correct data
  3. reload the page: it automatically connects and opens the port
  4. after a couple of commands, it begins to queue them
  5. reloading again: it continues to queue commands
  6. but, closing and reopening the serial port (only) brings back the correct behavior (i.e. no more queue and answers are received).

So I didn't restart the server (good!), I didn't see any "messed up" string and the needs to close and re-open the port to avoid the queue is ok.

Hence there's something wrong in my code, I bet.

TemperedEnterprises commented 6 years ago

https://github.com/johnlauer/serial-port-json-server/issues/39

This issue was documented by me way back in 2016 - but because I lack personal skills it was ignored.

https://www.youtube.com/watch?v=70uAKhbGXIk

The issue has to do with the handling of the PORT open command. The SPJS expects the user to check if the port is open before opening the port. If the user opens the same port multiple times, my guess is that the SPJS software just creates more threads parsing input of the serial port. So some characters go to one thread but other characters are handled by a different thread. It basically breaks the parsing of JSON.

An easy fix would be to simply check to see if the port is open, and if the port open request is based on the same parameters, just ignore the request. Otherwise, just close the port and re-open it? << this last idea could be problematic if you are in a CNC program executing and someone opens up a new terminal on a new workstation.

But as my experience with code and troubleshooting is not appreciated here - I will not be publishing the fix.

It truly is sad, here I came with an issue and was willing to troubleshoot it, isolate the bad code, publish my findings, and probably would have created a patch. But when I submitted the issue. instead of accepting that I could have something to bring to this project, the admins assumed I just didn't know what I was doing.

Then got really irate and "offended" when I tried to explain I didn't need help - i was here to help.

Anyways - good luck with a bug the developers refuse to fix because I brought it to them and they hate me over trivialness.

TemperedEnterprises commented 6 years ago

And I was attempting to bring effort to the table. I was working on this app, https://play.google.com/store/apps/details?id=com.temperedenterprises.com.openbuilds.pendant

That was written in Xamarin so it was working on both iOS and Android Devices. The current version was a basic design/proof of concept. I took one shortcut - I was controlling the SPJS server blind. In other words, I was sending the server commands and not parsing the response/ignoring the response.

This is why I stumbled on the bug first - my sloppy code exacerbated the problem.

Anyways, I discontinued the Xamarin pendant project - but if anyone wants me to - I will publish the code open source on Github.

TemperedEnterprises commented 6 years ago

And the basic problem with the design of using networks to check a state for a safe position and then only open the port if it isn't already open - is because in a multi-client multi-application multi-threaded environment - you can't guarantee that the port wasn't opened 1ms after you queried the port to see if it was open.

So basically, the fix has to be implemented on the SPJS server code to be effective.