• Как грамотно спроектировать backend real-time приложения?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Архитектурно правильно иметь 1 соединение для транспорта данных. Это экономит ресурсы.
    Далее вам нужен роутинг сообщений.
    Например: селекты обрабатываются модулем страницы, а сообщения в чате - модулем чата.
    Реализуется все это достаточно тривиально через шину событий.
    Ответ написан
    Комментировать
  • Как раскрутить чат в телеграме?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Реклама двигатель торговли.

    Чат в телеграме - пустая трата времени и денег. Сделайте местную рекламу курсов для людей живущих поблизости. Если у вас онлайн школа - сделайте рекламу онлайн с лидогенерацией.
    Ответ написан
    Комментировать
  • Пропадает память. Как тренировать?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Необходимо найти баланс. Это трудно.
    1. Охранять сон. Послать всех куда-подальше и начать высыпаться.
    2. Ограничить рабочее время. Привет режим с 8 до 5. Я серьезно.
    3. Физическая активность. Заставьте себя ходить хотя бы час в день. Полчаса на работу, полчаса с работы. Выходите на несколько остановок раньше и идите. Если добираетесь на своем транспорте - паркуйтесь дальше от офиса.
    4. Отдых со сменой обстановки - поехать в другой город, на дачу, навестить родителей. Например можно поехать в соседний город. В Москве - в район, где не были или в подмосковье. Обязательно, чтобы была смена обстановки и внешнего вида. В этом плане здорово влияет рыбалка с удочкой в одиночку. Помогает расслабиться, неспешно подумать обо всем. Успокаивает нервы.
    5. Отказаться от вредных привычек. Не переедайте, не курите, не бухайте чересчур. Полностью и резко отказываться не надо, а уменьшить можно.
    6. Жене один раз сказать, что если не перестанет на вас орать, то к 45 вместо вас у нее останется холмик сырой земли. И если у нее есть с этим проблемы, пусть идет к психологу.
    7. Выгружать мелочи из головы в семейный календарик, приучать жену к нему (у меня так много знакомых делает, у кого несколько детей, там секции, праздники, всякие расписания).
    Ответ написан
    1 комментарий
  • Как организовать обмен данными на сервисе, ежесекундно принимающем новые данные?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Использовать Laravel для таких задач идея рабочая, но не очень здравая. Насчет производительности - все зависит от того, сколько денег вы готовы потратить на инфраструктуру. А так - справится прекрасно, если клиентов ну до 1000 онлайн. Дальше у вас начнутся проблемы вертикального масштабирования. Вы может еще немного потянете, но все равно это закончится в какой-то момент.
    Если хотите держать много соединений, то https://nchan.io/ вам подойдет идеально.
    Ответ написан
    2 комментария
  • Сложный и интересный проект для новичка?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Вот вам сложная задача: написать онлайн-калькулятор, который будет определять оптимальный порядок загрузки фуры. У вас есть габариты кузова и тоннаж, дальше пронумерованные коробки с размерами, весом и признаком хрупкости в виде веса, который может быть и нулевым. Результат вывести в виде трехмерной картинки и таблицы с порядком загрузки коробок. При наведении на строку в таблице, коробка должна подсвечиваться.
    Результат разработки нужно разместить на github.
    Ответ написан
    6 комментариев
  • Как данное реализуется?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Реализуется достаточно просто.
    У вас один nodejs процесс слушает TCP порт 80. Браузер может создавать множество соединений с сервером, как короткоживущих, вроде GET/POST, так и долговременных, как WebSockets.
    Websockets используют механизм апгрейда соединения, суть которого заключается в изменении самого протокола верхнего уровня при установлении TCP соединения. Простыми словами, сначала веб-сокеты цепляются по обычному HTTP, потом шлют заголовки Upgrade: WebSocket и Connection: Upgrade, после чего штаны (http) превращаются в элегантные брюки (websockets).
    Поэтому один и тот же сервер может обслуживать и веб-сокеты и http. На этом заканчивается магия одновременных соединений со стороны браузере с одним и тем же сервером по разным протоколам. Дальше начинается магия того, как передаются данные с одного протокола (http) в веб-сокет.
    Поскольку чат работает внутри одного процесса (это я нарочно упрощаю), то у процесса есть разделяемый обработчик событий. Через него сообщения пересылаются между обработчиками разных протоколов.

    В коде очень упрощенно это выглядит так:
    // импортируем зависимости
    
    import app from 'express';
    import { createServer } from 'http';
    import socketio from 'socket.io';
    
    // наш http сервер
    const app = express();
    const http = createServer(app);
    
    // наш websocket сервер
    const io = socketio(http);
    
    // глобальная шина сообщений
    const messageBus = new EventEmitter();
    
    // так мы получаем сообщение по http
    app.get('/message', (req, res) => {
    	console.log('http message:', req.params);
    	// и пихаем его дальше по шине сообщений
    	messageBus.emit('message', req.params);
    })
    
    // когда установлено соединение, 
    // мы можем настроить подписку на сообщения
    io.on('connection', (socket) => {
    	// соединение установлено!
    	console.log('Connected!');
    
    	// так мы подписываемся на сообщение
    	// приходящее через вебсокеты
    	socket.on('message', (message) => {
    		console.log('websockets message:', message);
    		// и шлем его дальше по шине сообщений
    		messageBus.emit('message', message);
    	});
    
    	// теперь мы подписываемся на любые сообщения
    	// вне зависимости от того, откуда они были получены,
    	// и пересылаем их всем через вебсокеты
    	messageBus.on('message', (message) => {
    		io.emit('message', message);
    	});
    
    });
    
    // слушаем по http порт 3000
    http.listen(3000, () => {
      console.log('запустились на порту 3000');
    });


    В реальной жизни вместо разделяемого объекта EventEmitter используется реальная шина сообщений на основе Redis Pub/Sub или очередей, вроде RabbitMQ. Такие штуки делаются для очень больших чатов, способных держать десятки и сотни тысяч человек онлайн. Например чаты в масштабах Youtube, Twitch и т.д.
    Для небольших чатов до несколько десятков тысяч пользователей вполне достаточно одного хорошо написанного сервера на Go.
    Nodejs не подходит для высоконагруженных проектов ввиду очевидно высокого уровня потребления ресурсов.
    Ответ написан
    4 комментария
  • Как сделать limit_req_zone для api token?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Ответ написан
    Комментировать
  • Веб-сервер на Node.js. Как организовать и контролировать сервис для прослушивания вебсокета для каждого активного пользователя?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Если вас волнует статическая типизация, то вам следует обратить внимание на Typescript и ts-node.

    По факту все делается достаточно просто при использовании JWT. Вот вам пример https://github.com/auth0-community/auth0-socketio-jwt

    Это поможет въехать в тему https://learn.javascript.ru/screencast/nodejs#node...
    Ответ написан
    Комментировать
  • Почему меняется кодировка при загрузке файла?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Вам нужно использовать application/octet-stream и напрочь убрать charset.
    Тут хороший пример заголовков https://www.php.net/manual/ru/function.readfile.php
    Ответ написан
    Комментировать
  • Как правильно делать счетчики на сайте?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Обычно для счетчиков стараются применять базы данных в памяти.
    В основном это Redis, но можно и MySQL использовать, просто указать хранилище в памяти и отключить транзакции.
    В большинстве своем счетчики обновляются на основе различных событий, например отправка комментария. Обновление делается в фоновом режиме.
    Как только данные актуализируются, интерфейс уведомляется о новом состоянии счетчиков. На больших сайтах это реализуется через SSE или веб-сокеты.
    Ответ написан
    Комментировать
  • Как написать нейросеть на Python?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Ответ написан
    Комментировать
  • Приведение типов в GO, можно сделать красивее?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Идея такой функции не самая здравая. Конверсия некоторых чисел будет вызывать непредсказуемое поведение.
    Что-то в духе uint64(2^32+1) может здорово пошатать ваш int64.
    Я советую вам не играть с огнем и рассмотреть альтернативные варианты работы с данными.
    Ответ написан
    Комментировать
  • Этот код сильно ужасен)?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Ну что же, начнём? Только не плакать потом, сами попросили.

    Итак, начнем с архитектуры. Начнем с того, что код чем только не занимается, он и из консоли запускает и как веб-хук и т.д. Сам по себе он является куском битрикса в том или ином виде.
    Далее - код использует ООП, но написан в процедурном стиле.

    Уже за это надо проявлять насилие над личностью.

    <?php
    include "bitrix.php";
    include "function.php";
    require_once  '../src/db.php';


    Просто используйте require_once.

    use должен быть вверху файла.

    $id = $_GET['id'];
    Будет генерировать ошибки, если скрипт был вызван без id.

    $select = $db->query("SELECT * FROM tg_bot WHERE  tg_bot.id='$id'");

    Добро пожаловать в мир SQL-инъекций.

    $bot_token = $select[0]['api_key'];
    Что произойдет, если бот не существует? Ошибки.

    define('BOT_TOKEN', "$bot_token");
    Бить железной линейкой по пальцам. Сильно. Больно. Долго.

    Нельзя использовать переменные внутри define. Эта инструкция придумана для объявления констант. Объявлять константы используя переменные недопустимо.

    if (php_sapi_name() == 'cli') {
        apiRequest('setWebhook', array('url' => isset($argv[1]) && $argv[1] == 'delete' ? '' : WEBHOOK_URL));
        exit;
    }

    Жуть какая-то.

    $content = file_get_contents("php://input");
    $update = json_decode($content, true);
    
    if (!$update) {
        exit;
    }

    Я так понимаю, что здесь происходит вызов самого веб-хука.

    Ну а дальше просто идет месиво. Смешались в кучу кони, люди...

    Что с этим можно сделать?

    Вызубрить ООП и getjump.github.io/ru-php-the-right-way

    Вспомните принцип "Разделяй и властвуй".
    Разделяйте код по функционалу и уровням абстрации.
    Например разделите код на работу с базой, на работу с API, на бизнес-логику.

    Например ваш код мог бы выглядеть так:

    // добавляем автозагрузку классов
    require_once 'vendor/autoload.php';
    // импортируем конфигурацию
    require_once 'config.php';
    
    use Chaly/Bot;
    
    // проверяем, что наш скрипт вызван с индентификтором бота
    if (!isset($_GET['id'])) {
      exit(1); // ненулевой статус говорит об ошибке
    }
    
    // загрузить робота из базы данных
    $bot = Bot::loadById($_GET['id']);
    if (!$bot) {
      exit(1);
    }
    
    // запустить робота
    $bot->run();


    Как может выглядеть тело run()

    public function run() {
      if (Cli::isValid()) {
        switch (Cli::getCommand()) {
            case 'delete':
                $this->delete();
                break;
            case 'register':
                $this->register();
                break;
        }
        return;
      }
    
      $payload = $this->getWebHookPayload();
      if (!$payload) {
        return;
      }
    
      if (isset($payload['message'])) {
        $this->interpretMessage($payload['message']);
      }
    
      // и так далее, думаю смысл понятен
    }
    Ответ написан
    3 комментария
  • Собственные проекты. Стоит ли доводить до идеала?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Есть смысл тогда, когда это приносит вам доход или способствует совершенствованию навыков.

    Отличный показатель - написал простую бесплатную игру - она случайно попала в топ и на нее обратили внимание. Разумеется, в таком случае народ будет смотреть ваш код и учиться на нем.
    Ответ написан
    Комментировать
  • Какой вариант компонента объективно лучше?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    А разве нельзя написать это по-человечески?
    Я Vue не знаю, но из предложенных вариантов представляю себе это как-то так

    <accordion :items="items">
      <!-- add your content layout,
      in our case this is div  -->
      <div>{{item.content}}</div>
    </accordion>


    Я понятия не имею, но с моей точки зрения абсолютно логично использовать некоторого рода публичный интерфейс, строго декларирущий структуру items.
    Главный дочерний элемент становится шаблоном для отрисовки содержимого внутри аккордиона.

    Шаблон тимлида мне абсолютно понятен без каких-либо знаний Vue. Ваш шаблон напоминает какую-то вуду магию. Надо лезть в документацию и разбираться, что к чему.

    Могу предложить альтернативный вариант с прямым декларированием структурных элементов.

    <v-accordion :items="items">
      <v-title>{{title}}</v-title>
      <v-content>{{content}}</v-content>
    </v-accordion>


    Я не знаю, можно ли обойтись без всего того мусора, но его наличие меня раздражает.
    Ответ написан
    Комментировать
  • Как изготовить лодку способную на плаву преодолеть лабиринт, не касаясь стенок?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    2-х датчиков расстояния недостаточно. Нужно 4 для корректной навигации внутри лабиринта. Располагаются под углом 45 градусов относительно осевой линии лодки.
    Дальше вам нужно будет освоить PID регулятор и реализовать алгоритм прохождения лабиринта.
    Ответ написан
  • Как определить склеить несколько сообщений в одно в случаях, когда -- пользователи -- отправляют -- одно сообщение -- несколькими?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Для этой задачи есть только одно решение - чат-бот должен понимать смысл текста. Пока эта проблема не решена.

    Пока эта проблема не решена - материться на юзера и просить его ввести текст полностью. В голосовых системах ввода окончание предложения определяется по интонации. В текстовых по завершению ввода.
    Ответ написан
    Комментировать
  • Способы разгрузки React-компонента от излишней бизнес-логики, DI в React?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Выделение бизнес-логики в сервис является стандартной практикой. Это не должно вас смущать.
    Кстати, вы можете шарить инстанс модели либо использовать одну модель из другой.
    Вообще код с mobx намного лаконичнее, чем в redux. Вы присмотритесь к нему внимательнее.
    Ответ написан
    Комментировать
  • Чем отрубать напругу?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    1. Предъявить претензию владельцам здания. Перезаключить договор с предоставлением выделенной электрической линии.
    2. Подключить оборудование проводом в металлической трубе/гофре. В обычную проводку втыкают иголки и воруют, видел такое.
    3. Подключить открытую розетку отдельным проводом от общего счетчика. Пусть платят все за общественное пользование.
    Ответ написан
    Комментировать
  • Продажа билетов на мероприятия в Facebook. Реально?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Читайте документацию внимательно https://developers.facebook.com/docs/graph-api/ref...
    Ответ написан
    Комментировать