public void onMessage(string data)
 {
     try
     {
         JSONObject json = new JSONObject(data);
         string type = (string)json.Get("type");
         if (type.Equals("candidate"))
         {
             IceCandidate candidate = new IceCandidate((string)json.Get("id"), json.GetInt("label"), (string)json.Get("candidate"));
             if (outerInstance.queuedRemoteCandidates != null)
             {
                 outerInstance.queuedRemoteCandidates.AddLast(candidate);
             }
             else
             {
                 outerInstance.pc.AddIceCandidate(candidate);
             }
         }
         else if (type.Equals("answer") || type.Equals("offer"))
         {
             SessionDescription sdp = new SessionDescription(SessionDescription.SessionDescriptionType.FromCanonicalForm(type), outerInstance.preferISAC((string)json.Get("sdp")));
             outerInstance.pc.SetRemoteDescription(outerInstance.sdpObserver, sdp);
         }
         else if (type.Equals("bye"))
         {
             outerInstance.logAndToast("Remote end hung up; dropping PeerConnection");
             outerInstance.disconnectAndExit();
         }
         else
         {
             throw new Exception("Unexpected message: " + data);
         }
     }
     catch (JSONException e)
     {
         throw new Exception("Error", e);
     }
 }