Good morning, I don’t know if you have already got your solution, but I can help with a solution that works on some of my systems.
Server side
php server.
<?php
$host = '127.0.0.1';
$port = '9000';
$null = NULL;
above vc defines your host, connection port and variable with null value.
Note. Important vc set the host with the address of your server (IP).
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socket, 0, $port);
socket_listen($socket);
$clients = array($socket);
while (true) {
$changed = $clients;
socket_select($changed, $null, $null, 0, 10);
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket);
$clients[] = $socket_new;
$header = socket_read($socket_new, 1024);
perform_handshaking($header, $socket_new, $host, $port);
socket_getpeername($socket_new, $ip);
$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected')));
send_message($response);
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}
At this point 'below' I start creating an array that will be converted into json. This data will be released in the socket tunnel, that is, the communication between your server and client will be done by this json.
Obs. these values can be defined according to your need and utility.
foreach ($changed as $changed_socket) {
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
$received_text = unmask($buf); //unmask data
$tst_msg = json_decode($received_text);
$user_id_cliente = $tst_msg->id_cliente;
$empresa_id = $tst_msg->empresa_id;
$user_time_mensagem = $tst_msg->time_mensagem;
$user_conteudo_mensagem = $tst_msg->conteudo_mensagem;
$user_nome_cliente = $tst_msg->nome_cliente;
$quem_esta_enviado = $tst_msg->quem_envia;
$produto_detalhes = $tst_msg->produto_detalhes;
$grupo_men = $tst_msg->grupo_mensagem;
$nome_empresa = $tst_msg->nome_empresa;
$regra_empresa = $tst_msg->regra_empresa;
$atacado_empresa = $tst_msg->atacado_empresa;
$min_empresa = $tst_msg->min_empresa;
$cidade_cliente = $tst_msg->cidade_cliente;
$valor_pedido = $tst_msg->valor_pedido;
$pedido_mandar = $tst_msg->pedido_mandar;
$response_text = mask(json_encode(array('nome_empresa'=>$nome_empresa,'grupo_mensagem'=>$grupo_men,'pedido_mandar'=>$pedido_mandar,'regra_empresa'=>$regra_empresa,'atacado_empresa'=>$atacado_empresa,'min_empresa'=>$min_empresa,'cidade_cliente'=>$cidade_cliente,'valor_pedido'=>$valor_pedido,'produto_detalhes'=>$produto_detalhes,'quem_envia'=>$quem_esta_enviado,'empresa_id'=>$empresa_id,'id_cliente'=>$user_id_cliente, 'time_mensagem'=>$user_time_mensagem, 'conteudo_mensagem'=>$user_conteudo_mensagem, 'nome_cliente'=>$user_nome_cliente)));
send_message($response_text); //send data
break 2; //exist this loop
}
continuing...
$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) {
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));
send_message($response);
}
}
}
socket_close($socket);
function send_message($msg)
{
global $clients;
foreach($clients as $changed_socket)
{
@socket_write($changed_socket,$msg,strlen($msg));
}
return true;
}
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;
}
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;
}
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')));
$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/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
}
Client side your-file.js
remember the host and the port? are inserted below
var wsUrir = "ws://127.0.0.1:9000";
connection = new WebSocket(wsUrir);
open connection, activates the block below
connection.onopen = function(ev) {
console.log('socket aberto');
};
transactions, messages, requests, etc., run below.
connection.onmessage = function(ev) {
var msg_ws = JSON.parse(ev.data);
var type_ws = msg_ws.type;
var ws_id_cliente = msg_ws.id_cliente;
console.log(ev.data);
if(type_ws !== 'system'){
// suas condições aqui
}
};
if an error occurs during or after connection the function below is triggered.
connection.onerror = function(ev){
console.log("Error Occurred - "+ev.data);
};
if the connection closes, below is triggered
connection.onclose = function(ev){
console.log("conexao fechada");
};
After configuring your files you will have to access your terminal, navigate to the directory that is the file php server. and enter the command:
php -q **server.php**
obs. make sure you have php installed and that variable php be global in your OS.
Another important note is that the socket server only works in php with this command line call, that is, if you try to access by url right in the browser the file will not run and if you close the connection will also be terminated.
Anyway, if you have any questions contact me, what I know I share. Hugs!
I ended up making an ajax system that keeps checking if there is a new message in the bank. From the performance point of view it is a tragedy. I will try to apply your solution. Thank you.
– Gustave Dupre
Boy, like you said, it’s literally a tragedy, I had this same idea that you at the beginning of my project and suffered a lot until you know the socket, see, this code works very well for me I’m sure it will work for you too, if you have doubts do not hesitate to ask me.
– Luiz Augusto Neto
@Luizaugustoneto as the client-side code to send the messages to the server?
– Denied