Ответы пользователя по тегу JavaScript
  • Как отправить данные через websoket из php?

    @aspirantes
    Примерно так. Одно время копал в сторону веб-сокетов. Есть готовые наработки для дэймона и для чата. На просторах интернета готовый код не нашёл, только библиотеки, поэтому подгонял по RFC сам.

    Общий принцип - правильно кодировать и декодировать. Ну и само собой у серверов, куда подключаешься, тоже свои заморочки имеются.

    $context = stream_context_create(
      [
          'ssl' => [
            'disable_compression' => true
          ],
      ]
    );
    $fp = stream_socket_client("ssl://example.com:9443", $errstr, $errno, 30, STREAM_CLIENT_CONNECT, $context);
        if (!$fp) {
            echo "$errstr ($errno)<br />\n";
        } else {
            echo "true\n";
            fwrite($fp, "POST /ws/stream HTTP/1.1\r\n" .
                "Host: example.com\r\n" .
                "Accept: */*\r\n" .
                "Cache-Control: no-cache\r\n" .
                "Sec-WebSocket-Key: qwerty123\r\n" .
                "X-Mbx-Apikey: $akey\r\n" .
                "Connection: Upgrade\r\n" .
                "Upgrade: websocket\r\n\r\n");
                $old  = time() + 180000000;
            fwrite($fp, $data);
            while (!feof($fp)) {
                $stat = fstat($fp);
                $fp2 = fread($fp, 8192);
                $new = time();
                $fp2 = decode($fp2);
                if ($fp2['opcode'] == 9) {
                    fwrite($fp, encode($new, 'ping'));
                    echo "\nPING\n\n";
                };
                if (isset(json_decode($fp2['message'])->data->p)) $fp3 = json_decode($fp2['message'])->data->p;
                if (isset($fp3)) echo $fp3."\n";
                print_r($fp2)."\n";
            }
    }
    fclose($fp);
    echo('close');
    
    function decode($str, $message_only = false)
        {
            /* Разбираем заголовок */
            if (empty($str)) return "\n\n Пустое значение \n\n";
            $header = unpack("n", $str)[1];         /* Рапаковываем первые 16 бит, порядок байт «big endian», т.к. сетевой протокол */
            $data = [];
            $data['fin']            = (bool) (($header >> (16 - 1))  & 0b1);        /* Финальный фрейм. Если сообщение нефрагмантированное, то всегда 1, если фрагмантированно, то у последнего 1 у остальных 0 */
            $data['rsv1']           = (bool) (($header >> (16 - 2))  & 0b1);        /* Флаги RSV1, RSV2, RSV3 служат для расширений протокола, почти всегда в false */
            $data['rsv2']           = (bool) (($header >> (16 - 3))  & 0b1);
            $data['rsv3']           = (bool) (($header >> (16 - 4))  & 0b1);
            $data['opcode']         = (int)  (($header >> (16 - 8))  & 0b1111);     /* Тип фрейма */
            $data['is_mask']        = (bool) (($header >> (16 - 9))  & 0b1);        /* Замаскированы ли фреймы */
            $data['length_prev']    = (int)  (($header >> (16 - 16)) & 0b1111111);  /* Предварительная длина фрейма */
    
            /* Определяем тип фрейма */
            switch ($data['opcode']) {
                case '1':
                    $data['type'] = '1'; //text
                    break;
                case '2':
                    $data['type'] = '2'; //binary
                    break;
                case '8':
                    $data['type'] = '8'; //close
                    break;
                case '9':
                    $data['type'] = '9'; //ping
                    break;
                case '10':
                    $data['type'] = '10'; //pong
                    break;
                default:
                    break;
            }
    
            /* Определяем длину фрейма */
            if ($data['length_prev'] < 126)
            {
                $data['length'] = $data['length_prev'];
            }
            elseif ($data['length_prev'] === 126)
            {
                $data['length'] = unpack("x2/n", $str)[1];
            }
            elseif ($data['length_prev'] > 126)
            {
    //          $data['length'] = unpack("x2/J", $str)[1];
                $data['length'] = unpack("x2/x4/N", $str)[1];
            }
    
            /* Маска */
            if ($data['is_mask'])
            {
                if ($data['length_prev'] < 126)
                {
                    $mask = substr($str, 2, 4);
                }
                elseif ($data['length_prev'] === 126)
                {
                    $mask = substr($str, 2 + 2, 4);
                }
                elseif ($data['length_prev'] > 126)
                {
                    $mask = substr($str, 2 + 8, 4);
                }
            }
    
            /* Тело запроса */
            $message_start = 2;
            if ($data['length_prev'] < 126)
            {
    
            }
            elseif ($data['length_prev'] === 126)
            {
                $message_start += 2;
            }
            elseif ($data['length_prev'] > 126)
            {
                $message_start += 8;
            }
    
            if ($data['is_mask'])
            {
                $message_start += 4;
            }
            $data['message_start'] = $message_start;
    
            $message = substr($str, $message_start, $data['length']);
    
            /* Размаскируем сообщение */
            if ($data['is_mask'])
            {
                $length = strlen($message);
    
                for ($i = 0; $i < $length; $i++) 
                {
                    $message[$i] = $message[$i] ^ $mask[$i % 4];
                }
            }
    
            $data['message'] = $message;
    
            /* Возвращаем сообщение */
            if ($message_only === false)
            {
                return $data;
            }
            else
            {
                return $data['message'];
            }
        }
    
        /**
         * Закодировать строку
         * 
         * @param string $str
         * @param boolean $is_mask
         * @return string
         */
        function encode($str, $ping = false, $is_mask = false)
        {
            $bin = "";
    
            /* Основные флаги */
            $data = 
            [
                "fin" => 0b1,
                "rsv1" => 0b0,
                "rsv2" => 0b0,
                "rsv3" => 0b0,
                "opcode" => 0x1,
                "is_mask" => $is_mask === true ? 0b1 : 0b0,
                "length" => strlen($str)
            ];
    
            if ($ping = 'ping') $data['opcode'] = 0xA;
    
            /* Предварительная длина */
            if ($data['length'] < 126)
            {
                $data['length_prev'] = $data['length'];
            }
            elseif ($data['length'] < 65536)
            {
                $data['length_prev'] = 126;
            }
            else
            {
                $data['length_prev'] = 127;
            }
    
            /* Заголовок */
            $header = $data['fin'];
            $header = $header << 1 | $data['rsv1'];
            $header = $header << 1 | $data['rsv2'];
            $header = $header << 1 | $data['rsv3'];
            $header = $header << 4 | $data['opcode'];
            $header = $header << 1 | $data['is_mask'];
            $header = $header << 7 | $data['length_prev'];
            $bin .= pack("n", $header);
    
            /* Расширенная длина тела */
            if ($data['length_prev'] === 126)
            {
                $bin .= pack("n", $data['length']);
            }
            elseif ($data['length_prev'] > 126)
            {
                $bin .= pack("x4N", $data['length']);
            }
    
            /* Маскировать сообщение */
            if ($is_mask)
            {
                $mask = substr(md5(microtime()), 0, 4);
                $bin .= $mask;
    
                $length = strlen($str);
                for ($i = 0; $i < $length; $i++) 
                {
                    $str[$i] = $str[$i] ^ $mask[$i % 4];
                }
            }
    
            $bin .= $str;
            print_r($bin)."\n";
            return $bin;
        }
    Ответ написан
    Комментировать
  • Как передать цифру из переменной JS в переменную PHP?

    @aspirantes
    Если нужно сообщение фронта с бэком, то самый верный вариант это websockets.
    Ответ написан
    4 комментария
  • Как разрешить только определенные значения?

    @aspirantes
    Это ведь самые азы.
    https://codepen.io/papagis/pen/yLEaVoe

    Нужно просто добавить условия.
    Ответ написан
    Комментировать
  • Как добавлять разметку html через js?

    @aspirantes
    var text;
    document.getElementById('infinite-scroll').insertAdjacentHTML('beforeend', text);


    https://codepen.io/papagis/pen/OJQJoxM
    Ответ написан
    Комментировать
  • Как заставить показать результат ajax запроса, после создания DOM элемента?

    @aspirantes Автор вопроса
    Нашёл годный вариант наконец-таки:
    count_onload = function () {
          if (document.getElementsByName("incount").length !== 0) {
              var inc = document.getElementsByName("incount");
               for (var i = 0; i <inc.length ; i++) {
                        incount(inc[i]);
                   }
              }
         }
    
        var ele = document.getElementsByName("incount")[0];
        console.log(ele);
        ele.addEventListener("load", count_onload(), false);
    
         //window.onloadFuncs.push(count_onload);
    Ответ написан
    Комментировать