Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

MarceloSB

Sockets PHP + websockets

Recommended Posts

Boa tarde colegas, 

 

Se alguém puder me dar uma luz, estou com uma dificuldade em relação ao sockets com php, já estou a dias tentando fazer mas ta difícil, rs. 


A aplicação basicamente tem uma pagina web que vai receber informações quando for incluído algum dado novo no banco de dados através de outra aplicação. 


Fiz da seguinte forma  PAINEL + SERVER PHPSOCKETs + ADMIN

Criei um arquivo em php (server.php) que vai ser o servidor de sockets. 
Eu execute ele pelo shell do linux: php -q server.php 192.168.15.3 8959

require_once("/var/www/html/controller/cfg-system.php");

$host = $argv[1]; //host
$port = $argv[2]; //port
$null = NULL; //null var

//
//set_time_limit(0);
//ob_implicit_flush();

//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

//bind socket to specified host
socket_bind($socket, 0, $port);

//listen to port
socket_listen($socket);

//create & add listning socket to the list
$clients = array($socket);

say( ascii_banner() );
say("PHP WebSocket Server running....");
say("Server Started : ".date('Y-m-d H:i:s'));
say("Listening on   : ".$host." port ".$port);
say("Master socket  : ".$socket."\n");
say(".... awaiting connections ...");
//start endless loop, so that our script doesn't stop
while (true) {
	//manage multipal connections
	$changed = $clients;
	//returns the socket resources in $changed array
	socket_select($changed, $null, $null, 0, 10);
	
	//check for new socket
	if (in_array($socket, $changed)) {
		$socket_new = socket_accept($socket); //accpet new socket
		if ($socket_new) say("$socket: Connected ...");
		$clients[] = $socket_new; //add socket to client array
		
		$header = socket_read($socket_new, 1024); //read data sent by the socket
		perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
		
		socket_getpeername($socket_new, $ip); //get ip address of connected socket
		$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.':'.$port.' connected'))); //prepare json data
		if ($response) send_message($response); //notify all users about new connection
		
		//make room for new socket
		$found_socket = array_search($socket, $changed);
		unset($changed[$found_socket]);
	}
	
	//loop through all connected sockets
	foreach ($changed as $changed_socket) {	
		
		//check for any incomming data
		while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
		{
			$received_text = unmask($buf); //unmask data
			$received_text = str_replace("\\" ,"",$received_text);
			$response_text = mask($received_text);
			
			if($response_text)send_message($response_text); //send data
			//}
			break 2; //exist this loop
		}
		
		$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
		if ($buf === false) { // check disconnected client
			// remove client for $clients array
			$found_socket = array_search($changed_socket, $clients);
			socket_getpeername($changed_socket, $ip);
			unset($clients[$found_socket]);
			
			//notify all users about disconnected connection
			$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.':'.$port.' disconnected')));
			if($response)send_message($response);
		}
	}
}
// close the listening socket
socket_close($socket);

function send_message($msg)
{
	global $clients;
	foreach($clients as $changed_socket)
	{
		if($msg) @socket_write($changed_socket,$msg,strlen($msg));
		//say("> ".$msg." (".strlen($msg). " bytes) \n");
	}
	return true;
}


//Unmask incoming framed message
function unmask($text) {
	$length = ord($text[1]) & 127;
	if($length == 126) {
		$masks = substr($text, 4, 4);
		$data = substr($text, 8);
	}
	elseif($length == 127) {
		$masks = substr($text, 10, 4);
		$data = substr($text, 14);
	}
	else {
		$masks = substr($text, 2, 4);
		$data = substr($text, 6);
	}
	$text = "";
	for ($i = 0; $i < strlen($data); ++$i) {
		$text .= $data[$i] ^ $masks[$i%4];
	}
	return $text;
}

//Encode message for transfer to client.
function mask($text)
{
	$b1 = 0x80 | (0x1 & 0x0f);
	$length = strlen($text);
	
	if($length <= 125)
		$header = pack('CC', $b1, $length);
	elseif($length > 125 && $length < 65536)
		$header = pack('CCn', $b1, 126, $length);
	elseif($length >= 65536)
		$header = pack('CCNN', $b1, 127, $length);
	return $header.$text;
}

//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
	$headers = array();
	$lines = preg_split("/\r\n/", $receved_header);
	foreach($lines as $line)
	{
		$line = chop($line);
		if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
		{
			$headers[$matches[1]] = $matches[2];
		}
	}

	$secKey    = @$headers['Sec-WebSocket-Key'];
	$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
	//hand shaking header
	$upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
	"Upgrade: websocket\r\n" .
	"Connection: Upgrade\r\n" .
	"WebSocket-Origin: $host\r\n" .
	"WebSocket-Location: ws://$host:$port/panel/shout.php\r\n".
	"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
	socket_write($client_conn,$upgrade,strlen($upgrade));
}

function ascii_banner() //just for old-skool fun...
{
	$banner="               _    ____             _        _   \n";
	$banner.=" __      _____| |__/ ___|  ___   ___| | _____| |_\n ";
	$banner.="\ \ /\ / / _ \ '_ \___ \ / _ \ / __| |/ / _ \ __|\n";
	$banner.="  \ V  V /  __/ |_) |__) | (_) | (__|   <  __/ |_ \n";
	$banner.="   \_/\_/ \___|_.__/____/ \___/ \___|_|\_\___|\__|\n";
	return $banner;
                                             
}

//utility functions
function say($msg=""){ echo $msg."\n"; } //display server console messages

E criei um outro arquivo que vou chamar de painel com websockets que é acesso via navegador  http://192.168.15.3/painel/
A ideia é que esse painel receba as informações que forem incluídas e ou alteradas pelo ADMIN.

Abaixo o script do websocket,  esta conectando e funcionando bem...

<script language="javascript" type="text/javascript">  
$(document).ready(function(){
	//create a new WebSocket object. {WS-HOST} = 192.168.15.3  {WS-PORT} = 8959
	var wsUri = "ws://{WS-HOST}:{WS-PORT}"; 	
	websocket = new WebSocket(wsUri); 
	websocket.onopen = function(ev) { // connection is open 
		$('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
		$('#md-alert').modal('show');
		//setTimeout(, 2000);
		setTimeout(function(){
		  	$('#md-alert').modal('hide');
		}, 6000);		
	}
	//#### Message received from server?
	websocket.onmessage = function(ev) {
		if (ev.data){
			var $msg      = JSON.parse(ev.data); //PHP sends Json data
			var $type     = $msg.type; //message type
			if($type == 'usermsg') {
				// mostro mensagems de users..
			}
			//Mensagens do sistema (sockets)
			if($type == 'system'){
				var $umsg   = $msg.message; //message text
				console.log($umsg + " " + $type);
			}
			//Conteudo...
			if($type == 'conteudo'){
				//Carrego o conteudo 
			}			
		}
	};
	websocket.onerror	= function(ev){
		console.log((ev.data));
	}; 
	websocket.onclose 	= function(ev){
		console.log((ev.data));
	}; 
});
</script>


O problema é agora!! Não estou conseguindo mandar as informações para o socket para o painel ler. 

NO ADMIN é outra url etc.: http://192.168.15.3/admin/  quando eu publicar o conteudo, logo após o insert no banco de dados, quero mandar essas informações para o socket.

Eu tentei usar o seguinte script:


/* Get the port for the WWW service. */
$service_port = '8959';

/* Get the IP address for the target host. */
$address = '192.168.15.3';

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);

$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . 
          socket_strerror(socket_last_error($socket)) . "\n";
} else echo "Socket conneted  $address: $service_port <br >";
if (socket_bind($socket, $address, $service_port)) {
    echo "Socket bound correctly";
}

$buf = 'Test Message'; // Aqui seria o resultado do insert..
$len = strlen($buf);
if (socket_sendto($socket, $buf, $len, 0x100,  $address, $service_port) !== FALSE) {
    echo "Message sent correctly";
}

 

 

 


 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por violin101
      Caros amigos, saudações.
       
      Por favor, poderiam me ajudar.

      Estou com a seguinte dúvida:
      --> como faço para para implementar o input código do produto, para quando o usuário digitar o ID o sistema espera de 1s a 2s, sem ter que pressionar a tecla ENTER.

      exemplo:
      código   ----   descrição
           1       -----   produto_A
       
      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.
       
      Humildemente peço desculpa por postar uma dúvida que tenho.

      Preciso salvar no MySql, os seguinte Registro:

      1 - Principal
      ====> minha dúvida começa aqui
      ==========> como faço para o Sistema Contar Automaticamente o que estiver despois do 1.____?
      1.01 - Matriz
      1.01.0001 - Estoque
      1.01.0002 - Oficina
      etc

      2 - Secundário
      2.01 - Loja_1
      2.01.0001 - Caixa
      2.01.0002 - Recepção
      etc
       
      Resumindo seria como se fosse um Cadastro de PLANO de CONTAS CONTÁBEIL.

      Grato,


      Cesar









       
    • Por violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer a orientação dos amigos.

      Preciso fazer um Relatório onde o usuário pode Gerar uma Lista com prazo para vencimento de: 15 / 20/ 30 dias da data atual.

      Tem como montar uma SQL para o sistema fazer uma busca no MySql por período ou dias próximo ao vencimento ?

      Tentei fazer assim, mas o SQL me traz tudo:
      $query = "SELECT faturamento.*, DATE_ADD(faturamento.dataVencimento, INTERVAL 30 DAY), fornecedor.* FROM faturamento INNER JOIN fornecedor ON fornecedor.idfornecedor = faturamento.id_fornecedor WHERE faturamento.statusFatur = 1 ORDER BY faturamento.idFaturamento $ordenar ";  
      Grato,
       
      Cesar
       
       
       
       
    • Por violin101
      Caros amigos, saudações
       
      Por favor, me perdoa em recorrer a orientação dos amigos, tenho uma dúvida.
       
      Gostaria de uma rotina onde o Sistema possa acusar para o usuário antes dos 30 dias, grifar na Tabela o aviso de vencimento próximo, por exemplo:
       
      Data Atual: 15/11/2024
                                           Vencimento
      Fornecedor.....................Data.....................Valor
      Fornecedor_1...........01/12/2024..........R$ 120,00 <== grifar a linha de Laranja
      Fornecedor_1...........01/01/2025..........R$ 130,00
      Fornecedor_2...........15/12/2024..........R$ 200,00 <== grifar a linha de Amarelo
      Fornecedor_2...........15/01/2025..........R$ 230,00
      Fornecedor_3...........20/12/2024..........R$ 150,00
       
      Alguém tem alguma dica ou leitura sobre este assunto ?

      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer a ajuda dos amigos, mas preciso entender uma processo que não estou conseguindo sucesso.

      Como mencionado no Título estou escrevendo um Sistema Web para Gerenciamento de Empresa.
       
      Minha dúvida, que preciso muito entender:
      - preciso agora escrever a Rotina para Emissão de NFe e essa parte não estou conseguindo.
       
      tenho assistido alguns vídeos e leituras, mas não estou conseguindo sucesso, já fiz toda as importações das LIB da NFePhp conforme orientação.

      Preciso de ajuda.

      Algum dos amigos tem conhecimento de algum passo-a-passo explicando a criação dessa rotina ?

      tenho visto alguns vídeos com LARAVEL, mas quando tento utilizar e converter para PHP+Codeiginter, dá uma fila de erros que não entendo, mesmo informando as lib necessárias.

      Alguns do amigo tem algum vídeo, leitura explicando essa parte ?

      Grato,

      Cesar.
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.