public static void OnTypingStatusReceivedCallback(IntPtr actionPtr, string roomTopic, int roomType, string serializedUser, int typingStatus)
        {
#if DEVELOPMENT_BUILD
            UnityEngine.Debug.Log(string.Format("Received typing status, roomId: {0}, roomType: {1}, user: {2}, typing status: {3}",
                                                roomTopic, roomType, serializedUser, typingStatus));
#endif

            if (actionPtr == IntPtr.Zero)
            {
                return;
            }

            var          user = new User(new JSONObject(serializedUser));
            TypingStatus receivedTypingStatus = (TypingStatus)typingStatus;

            if (roomType == RoomTypePublic)
            {
                var room = new PublicChatRoomIOSImpl(roomTopic);
                actionPtr.Cast <Action <IPublicChatRoom, User, TypingStatus> >().Invoke(room, user, receivedTypingStatus);
            }
            else if (roomType == RoomTypePrivate)
            {
                var room = new PrivateChatRoomIOSImpl(roomTopic);
                actionPtr.Cast <Action <IPrivateChatRoom, User, TypingStatus> >().Invoke(room, user, receivedTypingStatus);
            }
            else
            {
                throw new InvalidOperationException("Unknown room type: " + roomType);
            }
        }
        public static void OnMessageReceivedCallback(IntPtr actionPtr,
                                                     string roomTopic, int roomType, string serializedMessage)
        {
#if DEVELOPMENT_BUILD
            UnityEngine.Debug.Log(string.Format("Received message, roomId: {0}, roomType: {1}, message: {2}",
                                                roomTopic, roomType, serializedMessage));
#endif
            if (actionPtr == IntPtr.Zero)
            {
                return;
            }

            var message = ChatJsonUtils.ParseChatMessage(serializedMessage);

            if (roomType == RoomTypePublic)
            {
                var room = new PublicChatRoomIOSImpl(roomTopic);
                actionPtr.Cast <Action <IPublicChatRoom, ChatMessage> >().Invoke(room, message);
            }
            else if (roomType == RoomTypePrivate)
            {
                var room = new PrivateChatRoomIOSImpl(roomTopic);
                actionPtr.Cast <Action <IPrivateChatRoom, ChatMessage> >().Invoke(room, message);
            }
            else
            {
                throw new InvalidOperationException("Unknown room type: " + roomType);
            }
        }