public RosbridgeJson(string jsonString)
        {
            RosbridgeJson <Tmsg> message = JsonUtility.FromJson <RosbridgeJson <Tmsg> >(jsonString);

            this.op      = message.op;
            this.id      = message.id;
            this.topic   = message.topic;
            this.msg     = message.msg;
            this.type    = message.type;
            this.service = message.service;
        }
        private void OnMessage <Tmsg>(string message) where Tmsg : RosMessage
        {
//			Debug.LogWarning("OnMessage="+message);

            if ((message != null) && !message.Equals(string.Empty))
            {
                Topper topper = new Topper(message);

                if ("publish".Equals(topper.op))                  // Topic
                {
                    RosbridgeJson <Tmsg> rosbridgeJson = null;

                    foreach (var sub in this.subscribers)
                    {
                        // only consider subscribers with a matching topic
                        if (topper.topic != sub.Key.Topic)
                        {
                            continue;
                        }

                        if (rosbridgeJson == null)
                        {
                            rosbridgeJson = new RosbridgeJson <Tmsg>(message);
                        }

                        MessageTask newTask = new MessageTask(sub.Key, rosbridgeJson.msg);

                        lock (this.lockMsgQueue)
                        {
                            this.msgQueue[rosbridgeJson.topic].Enqueue(newTask);
                        }
                    }
                }
                else if ("call_service".Equals(topper.op))                 // Service
                {
                    RosbridgeJson <Tmsg> rosbridgeJson = new RosbridgeJson <Tmsg>(message);

                    foreach (var srv in this.serviceProviders)
                    {
                        if (srv.Key.Name == rosbridgeJson.service)
                        {
                            ServiceArgs args = null;
//							ServiceResponse response = null;

                            // if we have args, parse them (args are optional on services, though)
                            Match match = Regex.Match(message, @"""args""\s*:\s*({.*}),");
                            if (match.Success)
                            {
                                args = srv.Key.ParseRequest(match.Groups[1].Value);
                            }

                            // add service request to queue, to be processed later in Render()
                            lock (this.lockMsgQueue)
                            {
                                this.svcQueue[srv.Key.Name].Enqueue(new ServiceTask(srv.Key, args, rosbridgeJson.id));
                            }

                            break;                             // there should only be one server for each service
                        }
                    }
                }
                else
                {
                    Debug.LogWarning("Unhandled message:\n" + message);
                }
            }
            else
            {
                Debug.Log("Got an empty message from the web socket");
            }
        }