docs: function onStringMessage(data)
      {
          try
          {
              data = (scope.encode) ? JSON.parse(atob(data)) : JSON.parse(data);
          
              switch(data.ev)
              {
                  case InternalEvents.REDIRECT:
                  {
                      changeServer(data.data);
                      break;
                  }
                  case InternalEvents.CONNECTED:
                  {
                      scope.id = data.data;
                      if(scope.onConnected)
                      {
                          scope.onConnected(scope.id);
                      }
                      break;
                  }
                  case InternalEvents.JOINED_ROOM:
                  {
                      scope.roomUsers   = data.data.users;
                      scope.room        = data.data.room;
                      scope.params      = data.data.params;
                      scope.rtcId       = data.data.rtcId;
                      scope.useRTC      = data.data.useRTC;
                      scope.rtcFallback = data.data.rtcFallback;
                      scope.byteType    = data.data.byteType;
  
                      if(scope.onJoinedRoom)
                      {
                          scope.onJoinedRoom(scope.room,scope.params);
                      }
                      break;
                  }
                  case InternalEvents.ROOM_PARAMS:
                  {
                      scope.params = data.data;
                      if(scope.onRoomUpdate)
                      {
                          scope.onRoomUpdate(scope.params);
                      }
                      break;
                  }
                  case InternalEvents.USER_JOINED_ROOM:
                  {
                      if(scope.roomUsers)
                      {
                          var hasObject = false;
                          for(var num = 0; num < scope.roomUsers.length; num++)
                          {
                              if(scope.roomUsers[num].id==data.data.id)
                              {
                                  hasObject = true;
                                  break;
                              }
                          }
                          if(hasObject == false)
                          {
                              scope.roomUsers.push(data.data);
                          }
                      }
                      if(scope.onClientJoinedRoom)
                      {
                          scope.onClientJoinedRoom(data.data.id);
                      }
                      break;
                  }
                  case InternalEvents.LEFT_ROOM:
                  {
                      if(scope.roomUsers)
                      {
                          scope.roomUsers = [];
                      }
                      if(scope.onLeftRoom)
                      {
                          scope.onLeftRoom();
                      }
                      break;
                  }
                  case InternalEvents.USER_LEFT_ROOM:
                  {
                      if(scope.roomUsers)
                      {
                          for(var num = 0; num < scope.roomUsers.length; num++)
                          {
                              if(scope.roomUsers[num].id==data.data)
                              {
                                  scope.roomUsers.splice(num,1);
                                  break;
                              }
                          }
                      }
                      if(scope.onClientLeftRoom)
                      {
                          scope.onClientLeftRoom(data.data);
                      }
                      break;
                  }
                  case InternalEvents.SDP_DESCRIPTION:
                  {
                      if(scope.onSDPDescription)
                      {
                          scope.onSDPDescription(data.id,data.rtcId,data.data);
                      }
                      break;
                  }
                  case InternalEvents.ICE_CANDIDATE:
                  {
                      if(scope.onIceCandidate)
                      {
                          scope.onIceCandidate(data.id,data.data);
                      }
                      break;
                  }
                  case InternalEvents.RTC_FALLBACK_LIST:
                  {
                      scope.fallbackUsers = data.data;
                      
                      break;
                  }
                  case InternalEvents.RTC_FALLBACK:
                  {
                      if(scope.onRTCFallback)
                      {
                          scope.onRTCFallback(data.from,data.data,false);
                      }
                      break;
                  }
                  case InternalEvents.PING:
                  {
                      scope.send("0",MessageType.PING);
                      break;
                  }
                  default:
                  {
                      if(data.ev)
                      {
                          if(scope.onMessage)
                          {
                              scope.onMessage(data);
                          }
                      }
                      else
                      {
                          if(scope.onRawMessage)
                          {
                              scope.onRawMessage(data);
                          }
                      }
                      break;
                  }
              }
          }
          catch(e)
          {
              if(scope.onRawMessage)
              {
                  scope.onRawMessage(data);
              }
          }
      }