gazebosim / gz-launch

Run and manage programs and plugins.
https://gazebosim.org
Apache License 2.0
12 stars 17 forks source link

websocket server sends duplicate message headers in protos response #246

Closed mjay-cr closed 1 month ago

mjay-cr commented 9 months ago

Environment

Description

Steps to reproduce

  1. Install gz-harmonic
  2. On a terminal run gz sim -v 4 -s -r shapes.sdf
  3. In another terminal run gz launch -v 4 /usr/share/gz/gz-launch7/configs/websocket.gzlaunch
  4. Go to web app and click connect

Output

If you open up the dev-tools on the browswer and then look at console, you will see the error:

ERROR Error: duplicate name 'Any' in Namespace .gz.msgs
    add namespace.js:240
    parseType parse.js:354
    parseCommon parse.js:261
    parse parse.js:790
    onloadend gzweb.module.js:11673

Switching to network and filtering by WebSocket requests, you will see that gzweb sends protos request. (Looking at the gz_launch console log will also show that it has been received). Then the response, when viewed as UTF-8 will see the proto headers sent below. After Wrench message it seems to repeat? Response from gz-garden and gz-harmonic are attached. Note: that the web visualisation works with garden and fortress (as per the steps above)

gz-garden-response.txt gz-harmonic-response.txt

Not sure if these duplicate headers are the problem but seems like a bug

hughlv commented 6 months ago

Before this issue gets solved, what is the best workaround? I need to run gazebo as a websocket server so I can use gzweb2 to render on webpage.

mjay-cr commented 6 months ago

Before this issue gets solved, what is the best workaround? I need to run gazebo as a websocket server so I can use gzweb2 to render on webpage.

Not sure if this is helpful but my current "workaround" is to just not migrate to harmonic, this is the only thing that is stopping me from migrating from fortress.

VincidaB commented 1 month ago

After some testing, I was able to see that WebsocketServer.cc seem to receive the types in double on this line :

 gz::msgs::Factory::Types(types);

This would make it an issue with gz-msgs probably.

I was able to come-up with a dirty fix on the gz-launch side :

std::set<std::string> processedDescriptors;

// Get all the messages, and build a single proto to send to the client.
for (auto const &type : types)
{
  auto msg = gz::msgs::Factory::New(type);
  if (msg)
  {
    auto descriptor = msg->GetDescriptor();
    if (descriptor){
      std::string descriptorStr = descriptor->DebugString();
      std::string firstLine = descriptorStr.substr(0, descriptorStr.find('\n'));
      if (processedDescriptors.find(firstLine) != processedDescriptors.end())
      {
        gzdbg << "Skipping duplicate descriptor[" << firstLine << "]\n";
        continue; // Skip if the first line of the descriptor has already been processed
      }
      allProtos += descriptorStr;
      gzdbg << descriptorStr;
      processedDescriptors.insert(firstLine); // Mark this descriptor as processed
    }
    else
    {
      gzerr << "Failed to get the descriptor for message["
        << type << "]\n";
    }
  }
  else
  {
    gzerr << "Failed to build message[" << type << "].\n";
  }
}
iche033 commented 1 month ago

I created a couple of PRs:

I think that may fix the issue. I was able to get shapes.sdf working after these changes.