Node.js >v.4.x & EcmaScript 5/6/7 + TypeScript, Vue.js, PHP >v.5.x, Docker/Kubernetes, C#(.Net/Mono) & C++

Достижения

Все достижения (4)

Наибольший вклад в теги

Все теги (54)

Лучшие ответы пользователя

Все ответы (39)
  • Чем PHPMailer отличается от обычной mail() функций??

    TemaSM
    @TemaSM
    Fullstack, DevOps, InfSec
    Функция mail() в PHP по сути вызывает встроенную в систему почтовую программу - стандартно, это sendmail в linux (также, возможно использовать qmail, postfix, но для этого надо сначала сконфигурировать PHP через .ini файл).
    Подробнее про Mail в PHP: https://www.php.net/manual/ru/book.mail.php
    И про основную проблему кроссплатформенного использования: https://habr.com/ru/post/26518/

    PHPMailer - это мощная библиотека, реализующая почтовые транспорты, а не использующая sendmail как стандартная mail() функция. Имеет из коробки большое количество возможностей, таких как (в списке представлена лишь малая часть):
    • полная поддержка SMTP, Qmail, POP3, IDN, DKIM;
    • поддержка SSL и TLS;
    • работает на любой win32 и *nix платформе;
    • гибкость отладки;
    • определяемые вручную заголовки писем;
    • совмещение нескольких сообщений и вложений;
    • встроенная поддержка изображений;
    • умеет посылать письма с множественными: адресатами (TO), копиями (CC), BCC и REPLY-TO;
    • многослойные/альтернативные сообщения для клиентов, которые не могут читать HTML письма;
    • поддержка 8 бит, base64, бинарного режима, и пригодного для печати формата;
    • перенос слов (word wrap);
    • сообщения в виде HTML (шаблоны);
    • библиотека проверена на множестве SMTP серверах: Sendmail, qmail, Postfix, Imail, Exchange, Mercury, Courier;
    • библиотека используется под капотом таких гигантов: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla;

    Подробнее можно прочитать тут:
    https://jino.ru/journal/articles/pochta-phpmailer/
    https://www.sesmikcms.ru/pages/read/ischerpyvajusc...

    Помимо PHPMailer существуют и другие крутые библиотеки, оставляю список для интересующихся:
    Swiftmailer
    (Symfony) Mailer

    Если вы активно пользуетесь функцией mail() при разработке на PHP и до сих пор ещё не сталкивались с проблемами при её использовании на хостингах или на своих собственных серверах без соответствующего правильно настроенного окружения, то mail() вам идеально подходит. А когда столкнётесь с проблемами или захотите иметь больше возможностей из коробки, станут очевидными плюсы PHPMailer и других специализированных библиотек.
    Ответ написан
    1 комментарий
  • VestaCP на 8083 порте. Как используя субдомен получить доступ к ПУ?

    TemaSM
    @TemaSM Автор вопроса
    Fullstack, DevOps, InfSec
    UPD: ВНИМАНИЕ. Ответ был написан очень давно, многое поменялось с тех пор. Ответ скорее всего более не актуален.

    Все, 5 часов мучения вылились в отличный результат!
    Как я сделал:

    1)Идем в админку VestaCP в раздел WEB, редактируем основной домен(например domain.ru) и добавляем алиас вида: panel.domain.ru (вместо panel укажите путь, по которому при заходе Вы будете видеть VestaCP)
    2)Заходим в раздел DNS и проверяем записи этого же домена. Обязательно должна быть A запись с именем, которое Вы вводили до этого!
    3)Идем по пути /etc/nginx/conf.d/ - там будет файл вида 127.0.0.1.conf (только там ip вашего сервера) - очищаем содержимое этого файла и сохраняем.
    4)Далее идем по пути /usr/local/vesta/nginx/conf/ - там будет файл nginx.conf - открываем и редактируем:
    После # Vhost будет стоять блок виртуального хоста, примерно такой:
    server {
    	listen       	8083;
    	server_name     _;        
            root            /usr/local/vesta/web;
            charset         utf-8;


    Заменяем его на:
    server {
    	listen       	panel.domain.ru:80;
    	server_name     panel.domain.ru;        
            root            /usr/local/vesta/web;
            charset         utf-8;


    Теперь выше этого кода, но после # Vhost, добавляем это:
    server {
    		listen       domain.ru:80 default;
    		server_name  domain.ru;		
    		location / {
    			proxy_pass  http://domain.ru:8080;
    		}
    		}

    domain.ru - Меняйте на тот домен, для которого выставляли A запись в DNS разделе(он же и в WEB разделе)

    Теперь поясняю:
    С этого момента запросы к главному домену - основной nginx не обрабатывает, а родительский(в VestaCP) делает это именно так как нам необходимо!
    При заходе на domain.ru nginx перенаправляет нас на 8080 порт, который принимает пакеты и отображает нам содержимое.
    При заходе на panel.domain.ru nginx принимает запросы и выполняет их относительно Location'ов, которые выставлены ниже в файле конфигурации.

    Таким образом мы "убили сразу двух зайцев":
    1)Как бы переместили нашу панель на субдомен
    2)Везде в запросах убрали какие либо порты

    Всех благодарю за помощь!
    Ответ написан
    2 комментария
  • Как реализовать ограниченную длину для border?

    TemaSM
    @TemaSM
    Fullstack, DevOps, InfSec
    Можно сделать при помощи SVG + CSS (лаконичнее и лучше), можно при помощи чистого CSS без SVG.
    Также советую посмотреть на исходники сторонних библиотек/ui-фреймворков - там можно найти примеры качественной реализации подобных элементов.

    Готовый вариант:
    640332a93ec96319083802.png
    Код

    Переменная --circle-progress - контролирует остаток "заполненности"
    <main class="radial-progressbar">
      <svg>
        <circle class="circle-bg" cx="57" cy="57" r="52" />
        <circle class="circle-1" cx="57" cy="57" r="52" />
      </svg>
      <section>
        <h1>97</h1>
      </section>
    </main>

    :root {
      --circle-progress: 60;
    }
    
    body {
      display: grid;
      height: 100vh; 
      place-items: center;
      background: #FFF;
    }
    
    .radial-progressbar {
      position: relative;
    }
    
    .radial-progressbar svg {
      width: 114px;
      height: 114px;
      margin: 1em;
    }
    
    .radial-progressbar .circle-bg {
      fill: none;
      stroke-width: 10px;
      stroke: #1A2C34;
    }
    
    .radial-progressbar [class^="circle-"] {
      fill: rgba(26, 44, 52, 0.7);
      stroke-width: 10px;
      stroke-linecap: round;
      transform: rotate(-90deg);
      transform-origin: 50% 50%;
    }
    
    .radial-progressbar .circle-1 {
      stroke-dasharray: 360;
      stroke-dashoffset: var(--circle-progress);
      stroke: #fc9135;
    }
    
    .radial-progressbar section {
      display: flex;
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      place-items: center;
      justify-content: center;
      color: #FFF;
    }


    Подробнее тут:
    https://dev.to/shantanu_jana/circular-progress-bar...
    https://stackoverflow.com/questions/14222138/css-p...
    https://codepen.io/jo-asakura/pen/NWWrWj
    https://nikitahl.com/circle-progress-bar-css
    https://www.codewithrandom.com/2022/10/22/circular...
    Ответ написан
    Комментировать
  • В каком жизненном цикле Vue 3 закрыть соединение с вебсокетом после закрытия клиентом сайта?

    TemaSM
    @TemaSM
    Fullstack, DevOps, InfSec
    Надо понимать что вы имеете в виду под фразой "когда клиент выходит с сайта", и какие конкретно вебсокеты используете - стандартные, или либу Socket.io работающую по Websocket транспорту.
    • Если подразумеваете закрытие вкладки браузера клиентом (как пример), то в этот момент браузер разорвёт соединение с socket.io сервером, а на сервере произойдёт событие `disconnect` у конкретного сокета, который был привязан к данному подключению.
      Более того - при закрытии вкладки с сайтом, у Vue не вызывается `beforeUnmount` или `unmounted`, поэтому ваш код не сработает - клиент (браузер) ничего не отправит, сервер ничего не получит.
      *Но это можно реализовать самому через слушатель события `beforeunload` у `window` (правда событие не сработает, если произойдёт вылет браузера или самой ОС) , подробнее тут:
      https://forum.vuejs.org/t/detect-browser-close/5001/2
      https://developer.mozilla.org/en-US/docs/Web/API/B...
      https://developers.google.com/web/updates/2018/07/...
      https://developer.mozilla.org/en-US/docs/Web/API/W...

    • Если подразумеваете выход из учетной записи клиента на сайте, то ваш код сработает

    Пример обработки первого случая (когда клиент выходит с сайта закрывая вкладку) на серверной стороне, если используете Socket.io (по аналогии можно и с обычными вебсокетами, но там придётся детектить разрыв соединения на базе отсутствия ответа на ping-pong со стороны браузера):
    // https://socket.io/docs/v4/server-initialization/
    import * as Server from 'socket.io'
    const io = Server()
    io.listen(3000)
    
    // коллекция сокет-подключений
    const connections = new Set()
    
    // когда Socket.io сервер словил новое подключение
    io.on('connection', (s) => {
      // добавляем это подключение в коллекцию
      connections.add(s)
      // слушаем событие отключения сокета и реагируем на него
      s.once('disconnect', () => {
        // удаляем данное сокет-подключение из коллекции
        connections.delete(s)
      })
    })
    // connections.size - покажет размер коллекции, то есть количество подключенных клиентов к серверу Socket.io (онлайн на сайте в вашем случае)

    Однако данный код можно не использовать в таком виде, тк в Socket.io уже есть под капотом готовые функции и коллекции для работы с подключенными сокетами, поэтому нет необходимости создавать и хранить в памяти свои собственные списки сокет-подключений.
    Например в v4, количество/список подключенных клиентов можно получить таким способом:
    // https://socket.io/docs/v4/server-instance/#Server-engine
    io.engine.clientsCount
    // или:
    // https://socket.io/docs/v4/server-api/#namespace-allSockets
    await io.allSockets()
    Ответ написан
    1 комментарий
  • Как реализовать на сайте безопасную сделку?

    TemaSM
    @TemaSM
    Fullstack, DevOps, InfSec
    Да все верно сказал, Escrow, но только если на автомате и свое, то вот план:

    1 - Заказчик
    2 - Исполнитель

    1) Исполнитель выполнил работу, которую заказал заказчик, далее исполнитель загружает на сайт/сервис выполненную работу - она каким либо образом урезается(если звук, то накладываются доп помехи; если картинки, то вотермарки и все остальное в подобном духе).
    2) Заказчик получает уведомление СМС, email, Viber ... и заходит, чтобы оплатить работу.
    3) После выполнения оплаты, средства резервируются в системе(сайте).
    4) Заказчик получает доступ к демо-предпросмотру выполненной работы и прямо через сообщения на сайте сообщает исполнителю все ли нравится и что стоит изменить/добавить.
    5) Исполнитель может загружать новые образцы выполненной работы, а заказчик может наблюдать за изменениями, которые постоянно сохраняются в системе
    6) Как только заказчика все устраивает, он нажимает на кнопку подтверждения завершения сделки и в этот же момент, заказчик получает доступ к загруженной работе исполнителя без каких либо вотермарков, а исполнитель в свою очередь получает оплаченную ранее заказчиком сумму, но уже от имени системы. Далее исполнитель может выбрать куда выплатить средства(на счет системы, на карту, на электронные кошельки...)

    Если какой либо из сторон что-то не понравилось, каждый из участников сделки может открыть диспут и уже тогда к этой сделке подключится менеджер системы, который проследит всю историю переписки заказчика и исполнителя, включая все изменения выполняемой исполнителем работы.
    В итоге менеджер может заключить определенные решения.

    Таким образом у нас получился эдакий Escrow своего производства.

    P.S. Никогда не реализовывал подобную схему, а лишь изложил первое, что пришло в голову.
    Ответ написан
    1 комментарий

Лучшие вопросы пользователя

Все вопросы (1)