Пример #1
0
        /// <summary>
        /// Разбирает ответ от сервера
        /// По неизвестной причине в ответ на команду от сервера может прийти не полный ответ
        /// При отправке следующе команды можно получить продолжение ответа на предыдущую комаду
        /// при этом не обязательно овет на предыдущую команду будет заверщён.
        ///
        /// Обработка ответов сервера выполняется по следующему алгоритму.
        /// Все ответы полученные от сервера помещаются в буфер.
        /// После полученя каждого ответа анализируется содержимое буфера.
        /// Если буфер содержит полны ответ то этот полный ответ связывается с соответствующе командой
        /// и передается на обработку.
        ///
        /// </summary>
        /// <param name="responce"></param>
        /// <returns></returns>
        private string ParceResponse(string response)
        {
            MpdResponseCollection mpdresponse = new MpdResponseCollection();

            // Oтвет при ошибке начинается с ASC и заканчивается \n
            // Ответ при нормальном завершении заканчивается OK\n

            // Проверка 1
            // Строка начинается с символов OK\n - это значит что в начале строки содержится ответ
            // об успешном выполнении команды не возвращающей данных
            // Просто убираем этот ответ из входной строки
            if (response.StartsWith("OK\n", StringComparison.Ordinal))
            {
                response            = response.Remove(0, 3);
                mpdresponse.Command = _SentCommandQueue.Dequeue();
                mpdresponse.Keyword = MpdResponseCollection.ResponseKeyword.Ok;
                Task.Run(() => HandleResponse(mpdresponse));
            }

            // Проверка 2
            // Строка содержит символы \nOK\n - это значит что строка содержит полный ответ
            // об успешном выполнении команды возвращающей данные
            // Забираем этот ответ из входной строки и разбираем его
            if (response.Contains("\nOK\n"))
            {
                //Забираем из входной строки подстроку от начала до до символов ОК (вместе с ОК)
                int nextresponsestart = response.IndexOf("\nOK\n", StringComparison.Ordinal) + 4;

                string currentresponce = response.Substring(0, nextresponsestart);
                response = response.Remove(0, nextresponsestart);

                string[] lines = currentresponce.Split('\n');
                for (int i = 0; i < lines.Length - 2; i++)
                {
                    mpdresponse.Add(lines[i]);
                }
                mpdresponse.Keyword = MpdResponseCollection.ResponseKeyword.Ok;
                mpdresponse.Command = _SentCommandQueue.Dequeue();

                Task.Run(() => HandleResponse(mpdresponse));
            }

            // Проверка 3
            // Строка содержит символы ACK - это значит что строка содержит ответ с информацией
            // об ошибке при выполнении команды
            // Забираем этот ответ из входной строки и cообщаем об ошибке
            if (response.StartsWith("ACK", StringComparison.Ordinal))
            {
                int    newresponsestart = response.IndexOf("\n", StringComparison.Ordinal) + 1;
                string currentresponse  = response.Substring(0, newresponsestart);
                response = response.Remove(0, newresponsestart);
                NotifyError("Server return error : \n" + currentresponse);
                return(response);
            }
            return(response);
        }
Пример #2
0
        /// <summary>
        /// Read server responces and convert them into data objects
        /// </summary>
        private async Task HandleResponse(MpdResponseCollection response)
        {
            //bool handleResponseCriticalError = false;
            string errorMessage = string.Empty;

            try
            {
                switch (response.Command.Op)
                {
                case "update":      // в ответ на команду сервер возвращает" "updating_db: 1\n"  (Реализовано)
                case "stats": _Statistics.Update(response); break;

                case "status": _Status.Update(response); break;           // Реализовано

                case "currentsong": _CurrentSong.Update(response); break;

                case "lsinfo":
                    if (response.Count > 0)
                    {     //  Каталог не пустой
                        string currentfolder = string.Empty;
                        if (CurrentFolder.Length != 0)
                        {
                            currentfolder = CurrentFolder + "\\";
                        }
                        // Создаём временный список файлов и заполняем его данными из ответв сервера
                        ObservableObjectCollection <File> filelist = new ObservableObjectCollection <File>(_mainPage);
                        filelist.Update(response);

                        if (_filelistUpdatInProcess)
                        {
                            _filelistCancelUpdate = true;
                            while (_filelistUpdatInProcess)
                            {
                                await Task.Delay(TimeSpan.FromMilliseconds(100));
                            }
//                                while (_filelistUpdatInProcess);
                            _filelistCancelUpdate = false;
                        }
                        await UpdateFileList(filelist);
                    }
                    else
                    {      // Каталог не содержит файлов
                        _FileList.ClearAndNotify();
                    }
                    break;

                case "list":
                    switch (response.Command.Argument1)
                    {
                    case "genre": _Genres.Update(response); break;

                    case "artist": _Artists.Update(response); break;

                    case "album": _Albums.Update(response); break;

                    case "title": _Tracks.Update(response); break;
                    }
                    break;

                case "search": _Tracks.Update(response); break;

                case "playlistinfo": _Playlist.Update(response); break;

                case "listplaylists": _SavedPlaylists.Update(response); break;

                case "outputs":
                    if (response.Count > 0)
                    {
                        _Outputs.Update(response);
                    }
                    break;

                case "config":
                    break;

                default: break;
                }
                if (response.Command.Op != "status")
                {
                    NotifyCommandCompletion(response.Command.Op, "OK", response.Error);
                }
            }
            catch (BalboaNullValueException be)
            {
                _Terminating = true;
                errorMessage = string.Format(_resldr.GetString("NullValueExceptionMsg"),
                                             be.VariableName, be.MethodName, be.FileName, be.LineNumber);
            }
            catch (BalboaException be)
            {
                _Terminating = true;
                errorMessage = string.Format(_resldr.GetString("BalboaExceptionMsg"),
                                             be.MethodName, be.FileName, be.LineNumber, be.Message);
            }
            catch (Exception e)
            {
                _Terminating = true;
                string exceptionMessage = e.Message.Contains("\r\n") ? e.Message.Substring(0, e.Message.IndexOf("\r\n")) : e.Message;
                errorMessage = string.Format(_resldr.GetString("UnexpectedServerError"), exceptionMessage);
            }
            finally
            {
                if (_Terminating)
                {
                    //await Halt();
                    NotifyCriticalError(errorMessage);
                }
            }
        }