• Как удалить Listener в RecyclerView?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Есть смысл ставить один раз обработчик кликов на весь RecyclerView:
    https://medium.com/@harivigneshjayapalan/android-r...

    Ставить обработчики на каждый элемент списка — это перебор.
    Ответ написан
    Комментировать
  • Как защитить Websocket based сайт от DDoS атак?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Чат? — Отлично. Значит, у нас задача: отделить ботов от людей и забанить ботов.

    Я действую так:

    1. Собираю в оперативке на бэкенде статистику действий клиентов в разрезе IP.

    2. После (!) обработки запроса клиента на бэкенде проверяю по статистике, не бот ли это? Использую несколько метрик и три временных среза для контроля лимитов: последние 3 секунды (здесь отлавливаются самые глупые боты), последние 10 секунд (здесь уже боты поумнее), последние 3 минуты (здесь ловятся совсем хитрые боты).

    3. Если хотя-бы по одному из сочетаний метрика/период клиент выходит за границы дозволенного, объявляю его ботом.

    4. Автоматизированно добавляю для данного IP-шника запрещающее правило на ближайшем брандмауэре. В итоге трафик на бэкенд больше не приходит.

    5. Через месяц также автоматизированно удаляю IP-шник из черного списка брандмауэра.

    В итоге обычный бот живёт у меня на сервере примерно полсекунды, успевая сделать 3...4 запроса. Потом IP уходит в бан на месяц и общается только с брандмауэром. Бэкенд сидит спокойно и ковыряет в носу.
    Ответ написан
    Комментировать
  • Как лучше организовать API load testing в организации?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    У команды Яндекс.Танка выложены полезные материалы по этой теме:
    https://yandex.ru/dev/tank/
    Ответ написан
    Комментировать
  • Как работает extension_override_freepbx.conf FreePBX 14?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    У меня "extensions_override_freepbx.conf" работает без проблем.

    Машину перезапускать не нужно. Надо применить конфигурацию FreePBX (красная кнопка Apply Config в правом верхнем углу).

    Если кнопка Apply Config недоступна, вносим любое изменение в конфигурацию через веб-интерфейс, кнопка появится.

    P.S. Кстати, у вас опечатка в имени файла. Может быть, дело в этом?
    Ответ написан
    Комментировать
  • Почему не приходят уведомления Cloud Messaging?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Возможно, дело в опечатке:
    $message / $massage

    Не знаком с php, он ругается в таких случаях, или молчит?

    UPD:
    Судя по ответу fcm, запрос Гугл принимает. И на мобилу доставить должен. Похожая схема у меня работает отлично, единственное отличие — я отправляю не списком, а на одно устройство.

    Возможна проблема на принимающей стороне. Как вы обрабатываете входящее сообщение? С такими параметрами (указано "data", но нет "notification") никакого автоматического всплывающего уведомления не будет — сообщение нужно обрабатывать на мобиле программно.
    Ответ написан
    Комментировать
  • Как переходить на нужный экран при старте приложения?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    У меня первым открывается основной экран, где человек работает после авторизации.

    Чаще пользователь уже авторизован и именно этот сценарий мы оптимизируем с точки зрения скорости запуска приложения.
    Ответ написан
    7 комментариев
  • Как управлять состоянием Activity, внутри onActivityResult после вызова startActivityForResult?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Если не хочется хранить состояние, можно передавать идентификатор элемента туда-обратно в интентах:

    1. При вызове startActivityForResult добавляем в интент идентификатор элемента.
    2. При возврате результата методом setResult() добавляем в интент кроме фотографии, еще и идентификатор, полученный ранее.
    3. При обработке полученного результата в onActivityResult() получаем из интента фотографию и идентификатор элемента.

    UPD:
    Признаться, у меня для подобных задач реализован более удобный API.
    При вызове startActivityForResult() сразу передаю обработчик результата.
    А вся работа с requestCode скрыта в черном ящике.

    public class ShellActivity extends AppCompatActivity {
    
        public interface ActivityResultHandler {
            void onActivityResult(int resultCode, Intent intent);
        }
    
        public void startActivityForResult(Intent intent, ActivityResultHandler handler) {
            // implementation
        }
    }

    Upd 2. А в Kotlin-е еще интереснее получается, вызов в одну сроку:
    /**
     * Возвращает Intent (если RESULT_OK), либо null (если RESULT_CANCELED)
     * */
    suspend fun ShellActivity.startActivityForResult(request: Intent): Intent? {
        return suspendCoroutine {
            this.startActivityForResult(request) { resultCode, response ->
                if (resultCode == RESULT_OK) {
                    it.resume(response!!)
                } else {
                    it.resume(null)
                }
            }
        }
    }
    Ответ написан
  • Почему точка заменяется на запятую?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Потому что по-русски десятичный разделитель — запятая.

    А если надо в программистском формате — с точкой, то используем:
    int.ToString(CultureInfo.InvariantCulture)
    Ответ написан
    1 комментарий
  • Как правильно вставить ListView в Fragment?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    ScrollView может содержать только один вложенный элемент.

    Если надо больше — берем LinearLayout и в него уже вставляем несколько элементов.
    Ответ написан
    6 комментариев
  • Почему страницы сайтов "прыгают" вверх или остаются на месте при обновлении?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Вот так будет прыгать:
    <p><img src=picture.jpg></p>
    <p>Текст, текст, текст, текст, текст</p>


    А вот так не будет:
    <p><img src=picture2.jpg width=300 height=200></p>
    <p>Текст, текст, текст, текст, текст</p>


    Причина проста. Браузер всегда покажет абзац с текстом, не дожидаясь, пока загрузится картинка. Чтобы пользователь смог скоротать время за чтением текста.

    Но тут у браузера возникает вопрос:
    — А сколько свободного места оставлять под картинку?

    Если мы размеры сразу укажем в html (300*200), браузер воспользуется нашей подсказкой и оставит 200 пикселей по высоте пустого места, чтобы потом там отобразить загруженную картинку.

    Но если мы не укажем размеры картинки в html, у браузера этой информации не будет. Размер необходимого свободного места под картинку будет взят наобум. Следующий за картинкой текст будет нарисован на экране сразу после этого "наобум".

    Уже потом, когда пользователь успеет прочитать половину текста, а браузер — загрузить картинку, размер нужного для картинки места будет пересчитан. При этом текст придется сдвинуть вниз.

    Это и есть "прыжки" контента при загрузке страницы.

    P.S. То же самое касается любого динамического контента, который подгружается скриптами после загрузки страницы. Размеры контейнеров под динамический контент нужно указывать сразу.
    Ответ написан
    7 комментариев
  • Как включить нужные подсказки в VSCode (и отключить ненужные)?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    TypeScript хорошо помогает.

    https://channel9.msdn.com/Events/Build/2017/B8088
    Ответ написан
    Комментировать
  • Как реализовать устранение предупреждения CLS-несовместимости кода: CLSCompliant(false) vs pragma warning disable?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    CLS придуман как гарантия совместимости байт-кода сборок, скомпилированных из разных языков.
    В примере выше единственно, чего мы можем опасаться, это того, что завтра будет выпущен CLS-совместимый компилятор языка Х.З.#, и байт-код этого Х.З.# не сможет работать с нашими Items из C#, поскольку свойство Items не является CLS-совместимым.

    Если же все сборки, которые у нас будут вместе работать, написаны на одном языке — C#, проблемы не существует.

    На практике, если в иерархии assembly / type / member нигде атрибутов CLSCompliant не ставить, вся сборка считается не CLS-совместимой и никаких предупреждений не будет.
    https://docs.microsoft.com/en-us/dotnet/api/system...
    Ответ написан
    Комментировать
  • Как с помощью ARI отправить звонок на Queue?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Из приложения Stasis канал можно вернуть назад в dialplan с помощью операции "continue":

    https://wiki.asterisk.org/wiki/display/AST/Asteris...

    Хоть в Queue, хоть... куда угодно.
    Ответ написан
    Комментировать
  • С# стоимость приведения типа?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Говорят, стоимость высокая.
    https://switch-case.ru/73228064
    Ответ написан
    2 комментария
  • Как декорировать Expression?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Подобные задачи в работе возникают регулярно. Строю текст SQL-запроса вручную, безо всяких Linq to SQL.
    В зависимости от текущих потребностей, включаю в текст SQL-запроса те таблицы, условия, группировки и т.д., которые нужны.
    Ответ написан
  • Как работает сетевой сокет при записи/чтении?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    TCP-сокет - это транспортный уровень, его задача: передавать от отправителя получателю последовательность байт, при этом:
    а) байты не терять;
    б) доставлять эти байты именно в том порядке, в котором они были отправлены.

    На этом задачи сокета заканчиваются. Т.е. ваш вопрос не имеет отношения к сокетам.

    Вопрос о том, сколько надо читать (и ждать), решается не на транспортном, а на прикладном уровне. Т.е. перед вами фактически стоит задача: разработать протокол прикладного уровня - придумать правила, чего и сколько должна отправлять и ждать каждая из сторон сетевого взаимодействия.

    Один из простых способов решения этой задачи - заставить каждую сторону перед отправкой любых данных указывать длину этих данных (например, 4 байта).

    Тогда работа получателя в этом случае проста:
    1) читаем из сокета 4 байта - длину сообщения;
    2) читаем из сокета еще столько байт, сколько указано в длине сообщения.

    А на всякие там DataAvailable обращать внимания не стоит, они только вводят в заблуждение. Если нужного нам количества байт еще не поступило - ждем, когда поступит.

    Upd.
    NetworkStream.DataAvailable всего лишь показывает нам, что данные уже поступили и их можно забрать с помощью Read, однако ничего не говорит о том, сколько еще данных ожидается и уж тем более НЕ сигнализирует о том, что другая сторона закончила передачу данных:

    "Use the DataAvailable property to determine if data is ready to be read. If DataAvailable is true, a call to Read returns immediately."
    https://docs.microsoft.com/en-us/dotnet/api/system...
    Ответ написан
  • Отсутсвие await гарантирует выполнение async метода?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Вот так это делается:
    Task.Run(async () =>
    {
        try
        {
            await _notification.Notify();
        } catch(Exception ex) {
            // TODO: Логируем исключение
        }
    });
    Ответ написан
    Комментировать
  • Оправдано ли применение очередей сообщений и архитектуре с событийной моделью?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Регулярно использую похожую конструкцию. Пара моментов:
    1. Никогда не использую внешние универсальные очереди сообщений (MSMQ etc). Вместо этого - легкое простое специализированное решение для каждого конкретного случая.
    2. Всегда интегрирую в единое целое то, что вы называете "сервис данных", "диспетчер подписок" и "очереди сообщений".
    Ответ написан
    Комментировать
  • Почему не запускается микросервис?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Судя по всему, область действия блока "using (var scope..." следует расширить до конца метода.
    Т.е. перенести закрывающую скобку в самый низ.
    Ответ написан
    4 комментария
  • Как работать с БД Postgres и 1с?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    Соответствие между идентификаторами объектов конфигурации 1С и именами полей и таблиц СУБД:

    https://www.forum.mista.ru/topic.php?id=531348

    https://its.1c.ru/db/metod8dev#content:1798:hdoc
    Ответ написан
    Комментировать