/// <summary>
        /// Should be called at least once each frame. Calls any available callbacks for received messages.
        /// Note: MUST be called from Unity's main thread!
        /// </summary>
        public void Render()
        {
            float start   = Time.realtimeSinceStartup;  // time at start of this frame
            float max_dur = 0.5f * Time.fixedDeltaTime; // max time we want to spend working
            float dur     = 0.0f;                       // time spent so far processing messages

            while (dur < max_dur)
            {
                // get queued work to do
                List <MessageTask> msg_tasks = MessagePump();
                List <ServiceTask> svc_tasks = ServicePump();

                // bail if we have no work to do
                if (msg_tasks.Count == 0 && svc_tasks.Count == 0)
                {
                    break;
                }

                // call all msg subsriber callbacks
                foreach (var t in msg_tasks)
                {
                    _subscribers[t.getSubscriber()](t.getMsg());
                }

                // call all svc handlers
                foreach (var svc in svc_tasks)
                {
                    ServiceResponse response = null;

                    // invoke service handler
                    bool success = _serviceServers[svc.Service](svc.Request, out response);

                    Debug.Log("Sending service response: \n" + ROSBridgeMsg.ServiceResponse(success, svc.Service.topic, svc.id, JsonUtility.ToJson(response)));
                    // send response
                    _ws.SendAsync(ROSBridgeMsg.ServiceResponse(success, svc.Service.topic, svc.id, JsonUtility.ToJson(response)), null);
                }

                dur = Time.realtimeSinceStartup - start;
            }
        }