Mackaybravo
@Mackaybravo
программист, фрилансер

Бесконечная загрузка страницы websocket?

Добрый вечер. Практикуюсь с websocket на php. Добавил цикл для ответа. Но страница стала бесконечно обновляться. Использую ларавел.
клиент
if(isset($_POST['mas'])){

				$socket = stream_socket_client('tcp://127.0.0.1:1237');

				fwrite($socket, $_POST['mas']);

				while(!feof($socket)){ 
					echo fgets($socket, 1024); 	
				}
				fclose($socket);

			}

сервер
<?php

	$server = stream_socket_server('tcp://127.0.0.1:1237');

	while(true){
		$socket = stream_socket_accept($server);

		$info = fread($socket, 1024);

		$file = fopen('info.txt', 'a+');

		fwrite($file, $info);

		fclose($file);
		fclose($socket);
	}

	fclose($server);

?>

В чем ошибка?
  • Вопрос задан
  • 514 просмотров
Пригласить эксперта
Ответы на вопрос 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Ммм... в том что это никакого отношения к websocket-s не имеет? В приведенном вами коде просто работа с TCP-стримами. Даже не сокетами (в общем-то разница не так уж велика, стримы просто абстракция сверху).
Ответ написан
Комментировать
MaxAlexQNEI
@MaxAlexQNEI
Web-Developer
То что вы представили это просто общение двух клиентов через консоль системы.
WebSocket намного хитрее.

Вебсокет подозревает использование WebSocket на JavaScript. А WebSocket сервер пишется и запускается на PHP.

Вот PHP-сокет сервер:

define( "E", PHP_EOL );
define( "E2", E . E );
define( "TAB", "\t" );
define( "STAB", "\s\s\s\s" );
define( "START", microtime() );
define( "ROOT", dirname( __FILE__ ) . "/" );

//define( "SOCK_ADDR", "46.149.84.91" );
define( "SOCK_ADDR", "192.168.0.2" );
define( "SOCK_PORT", 2424 );

ob_start();
ob_implicit_flush( TRUE );
set_time_limit( 0 );
ini_set( "date.timezone", "Europe/Kiev" );
ini_set( "display_errors", TRUE );
ini_set( "error_reporting", E_ERROR );
//ini_set( "output_buffering", TRUE );

header( "Content-Type: text/plain; charset=UTF-8" );

// AF_INET - 2
// SOCK_STREAM - 1
// SOL_TCP - 6
if( ( $socket = socket_create( 2, 1, 6 ) ) === FALSE ) {
    socket_return( "ERROR#0000: " . socket_strerror( socket_last_error( $socket ) ) );
} else {
    socket_return( "SOCKET SERVER is RUNNING" );
}

if( socket_bind( $socket, SOCK_ADDR, SOCK_PORT ) === FALSE ) {
    socket_return( "ERROR#0001: " . socket_strerror( socket_last_error( $socket ) ) );
} else {
    socket_return( "SOCKET SERVER is ATTACHED" );
}

if( socket_listen( $socket, 64 ) === FALSE ) {
    socket_return( "ERROR#0002: " . socket_strerror( socket_last_error( $socket ) ) );
} else {
    socket_return( "SOCKET SERVER is LISTENING" );
}

$abort = FALSE;
$clients = [];
$buffer_size = 2048;

$ms = 50;
$nano = $ms * 1e6;

socket_return( "BUFFER SIZE = {$buffer_size} bytes" );

while( !$abort ) {
    time_nanosleep( 0, $nano );
    
    $read = $clients;
    $read[] = $socket;
    $write = $except = NULL;
    
    if( !socket_select( $read, $write, $except, NULL ) ) {
        break;
    }
    
    if( in_array( $socket, $read ) ) {
        $clients[] = $client = socket_accept( $socket );
        unset( $read[ array_search( $socket, $read ) ] );
        socket_return( "New connection! {$client}" );
    }
    
    foreach( $read as $client ) {
        $buffer = rtrim( socket_read( $client, $buffer_size ) );
        
        if( empty( $buffer ) ) {
            socket_close( $client );
            unset( $clients[ array_search( $client, $clients ) ] );
            socket_return( "«{$client}» buffer: {$buffer}" );
            socket_return( "«{$client}» disconnected!" );
            continue;
        }
        
        socket_return( "«{$client}» say's: {$buffer}" );
    }
}

function socket_return( $text, $datetime = TRUE ) {
    echo $output = ( $datetime ? "[". date( "Y-m-d H:i:s" ) ."]" : NULL ) ." {$text}" . E;
    ob_flush();
    return $output;
}


Это так сказать собранный мною сокет-сервер из немалого количества статей из интернета.
А ВебСокет это еще больший "МАРАЗМ". Так как ВебСокет это общение из JavaScript объекта WebSocket с PHP-сокет сервером.

В этом JS WebSocket есть хитрость. Нужно писать энкодер-декодер. Так как общение происходит с помощью маски (от перехвата данных).

Вот ссылка на RFC - https://tools.ietf.org/html/rfc6455#section-5.2
Без энкодера-декодера - веб-сокета у Вас нет.

Код который я представил выше. Если у меня ноутбук не выключен. Вы можете подключится к серверу. Например, через терминал Linux: telnet 46.149.84.91 2424

А вот на Windows телнет походу бажит, так как отправка происходит по нажатию любой клавиши - а не после нажания Enter.

Тот сервер что я представил принимает до 64 клиентов (включительно).

Вот еще пример. Игра Agar.io - agar.io
Она так же использует WebSocket и убедится можно посмотрев один из JS-скриптов view-source:agar.io/main_out.js?v=34

Сервер же в любом случае использует енкодер и декодер (от этого не избавишься).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы