Usando PHP con Socket.io

128

¿Es posible usar Sockets.io en el lado del cliente y comunicarse con una aplicación basada en PHP en el servidor? ¿PHP incluso admite una forma de escritura de código de 'conexión duradera'?

Todo el código de muestra que encuentro para socket.io parece ser para node.js en el lado del servidor, por lo que no hay ayuda allí.

Yuvi
fuente
3
Posible duplicado: Socket.io de php source
hakre
Es posible que desee considerar solo empujador. Tiene una ingeniosa biblioteca PHP que usaré.
Devin G Rhode
hola, prueba este - github.com/walkor/phpsocket.io
Zhenya Hristova

Respuestas:

98

Puede que sea un poco tarde para responder esta pregunta, pero esto es lo que encontré.

No quiero debatir sobre el hecho de que los nodos lo hacen mejor que php o no, este no es el punto.

La solución es: no he encontrado ninguna implementación de socket.io para PHP.

Pero hay algunas formas de implementar WebSockets . Existe este complemento jQuery que le permite usar Websockets mientras degrada con gracia para navegadores no compatibles. En el lado de PHP, existe esta clase que parece ser la más utilizada para los servidores PHP WS.

Florian Margaine
fuente
1
la clase phpwebsocket es realmente el camino a seguir si desea una implementación del servidor php websocket. Sin embargo, esto no está relacionado con la pregunta. El OP ya tiene un servidor WS (socket.io) implementado y solicitó formas de comunicarse con una aplicación php.
Kasper Taeymans
72

Si quieres usar socket.io junto con php, ¡esta puede ser tu respuesta!

sitio web del proyecto:

elephant.io

también están en github:

https://github.com/wisembly/elephant.io

Elephant.io proporciona un cliente socket.io totalmente escrito en PHP que debería poder usarse en cualquier parte de su proyecto.

Es una biblioteca liviana y fácil de usar que tiene como objetivo brindar alguna funcionalidad en tiempo real a una aplicación PHP a través de socket.io y websockets para acciones que no se pudieron realizar en javascript completo.

ejemplo del sitio web del proyecto (comunicarse con el servidor websocket a través de php)

servidor php

use ElephantIO\Client as Elephant;

$elephant = new Elephant('http://localhost:8000', 'socket.io', 1, false, true, true);

$elephant->init();
$elephant->send(
    ElephantIOClient::TYPE_EVENT,
    null,
    null,
    json_encode(array('name' => 'foo', 'args' => 'bar'))
);
$elephant->close();

echo 'tryin to send `bar` to the event `foo`';

servidor io socket

var io = require('socket.io').listen(8000);

io.sockets.on('connection', function (socket) {
  console.log('user connected!');

  socket.on('foo', function (data) {
    console.log('here we are in action event and data is: ' + data);
  });
});
Kasper Taeymans
fuente
2
Te daré un +1 aquí, pero parece que esto todavía está un poco alejado de ser utilizable en un entorno de producción.
Beachhouse
17
He visto este, pero una cosa me confundió. ¿No es el punto aquí que PHP implemente un servidor sockets.io? y, en cambio, Elepant.io parece ser una implementación PHP de un cliente sockets.io para el que puede conectarse a algún otro servidor sockets.io (es decir, elephant.io no está escuchando las conexiones de sus clientes sockets.io, conectando a ellos y atenderlos)?
Pimp Trizkit
Justo lo que vine buscando, lástima que la conexión persistente se encuentre en una etapa temprana de desarrollo.
slezadav
8
Hola a todos. El objetivo de Elephant.io es simplemente disparar eventos desde PHP a un servidor socket.io. No para abrir una conexión persistente. Pero para poder conectarse rápidamente y enviar eventos / mensajes. Lo usamos en producción y funciona de maravilla.
guillaumepotier
3
esta biblioteca ya no se mantiene y tiene algunos problemas para nosotros
Flion
14

Si realmente desea utilizar PHP como back-end para socket.io, aquí está lo que encontré. Dos alternativas del lado del servidor socket.io php.

https://github.com/walkor/phpsocket.io

https://github.com/RickySu/phpsocket.io

Códigos de ejemplo para el primer repositorio como este.

use PHPSocketIO\SocketIO;

// listen port 2021 for socket.io client
$io = new SocketIO(2021);
$io->on('connection', function($socket)use($io){
  $socket->on('chat message', function($msg)use($io){
    $io->emit('chat message', $msg);
  });
});
walkor
fuente
7

Para la "conexión de larga duración" que mencionó, puede usar Ratchet para PHP. Es una biblioteca construida basada en las funciones de Stream Socket que PHP ha admitido desde PHP 5.

Para el lado del cliente, debe usar WebSocket compatible con HTML5 en lugar de Socket.io (como sabe, socket.io solo funciona con node.js).

En caso de que aún desee usar Socket.io, puede intentarlo de esta manera: - encuentre y obtenga socket.io.js para que el cliente lo use - trabaje con Ratchet para simular la forma en que socket.io lo hace en el servidor

¡Espero que esto ayude!

Chung Xa
fuente
6

Erm, ¿por qué quieres hacerlo? Deje PHP en el backend y NodeJS / Sockets para hacer lo que no bloquea.

Aquí hay algo para comenzar: http://groups.google.com/group/socket_io/browse_thread/thread/74a76896d2b72ccc

Personalmente, tengo Express corriendo con un punto final que está escuchando expresamente la interacción de PHP.

Por ejemplo, si le envié un correo electrónico a un usuario, quiero que socket.io muestre una notificación en tiempo real al usuario.

Desea la interacción de socket.io a php, bueno, puede hacer algo como esto:

var http = require('http'),
            host = WWW_HOST,
            clen = 'userid=' + userid,
            site = http.createClient(80, host),
            request = site.request("POST", "/modules/nodeim/includes/signonuser.inc.php",  
                {'host':host,'Content-Length':clen.length,'Content-Type':'application/x-www-form-urlencoded'});                     

request.write('userid=' + userid);      
request.end();  

En serio, PHP es ideal para hacer cosas del lado del servidor y dejarlo con las conexiones que no tiene lugar en este dominio ahora. ¿Por qué hacer encuestas largas cuando tiene websockets o flashsockets?

PaulM
fuente
32
Debido a que algunos de nosotros solo podemos obtener un host barato que solo le permitirá usar php y mysql.
Lanbo
31
Porque algunos de nosotros tenemos que trabajar con marcos existentes que dependen de PHP. Por ejemplo, desarrollamos y vendemos un script PHP, pero nos gustaría mejorar el IM mediante el uso de websockets, no queremos escribir todos los fallos que socket.io ya implementó, pero no podemos requerir NodeJS de nuestros clientes.
Purefan
3
@PaulM: Probé con pocos proveedores de VPS de <$ 10, y todos realmente apestan. Cada uno era muy lento, cuando algo se rompe, el soporte es horrible, etc. Por otro lado, en Finlandia no es raro obtener un alojamiento web de calidad decente (pero solo con archivos php / mysql / static) con suscripción adsl, sin pagar ningún extra . Entonces, no, poder comprar VPS horrible por $ 5 definitivamente no es una solución.
Olli
44
Para los proveedores de VPS de <$ 10, el único decente que he encontrado hasta ahora es digitalocean.com. Pero ese es bastante bueno.
Aeolun
3
No estoy de acuerdo Creo que una respuesta como esta es muy relevante. Alguien que te diga "lo estás usando mal" podría valer mucho más que alguien que te ayude a usarlo mal.
Rijk
6

¡Conozco al luchador! Pero recientemente lo tuve trabajando con Workerman. Si no te has topado con este marco de trabajo de PHP, ¡entonces mira esto!

Bueno, Workerman es un marco PHP asincrónico basado en eventos para construir fácilmente aplicaciones de red rápidas y escalables. (Acabo de copiar y pegar eso desde su sitio web jajajaja http://www.workerman.net/en/ )

La manera fácil de explicar esto es que, cuando se trata de programación de socket web, todo lo que realmente necesita tener es tener 2 archivos en su servidor o servidor local (donde sea que esté trabajando).

  1. server.php (código fuente que responderá a todas las solicitudes del cliente)

  2. client.php / client.html (código fuente que hará las cosas solicitadas)

Básicamente, primero debes corregir el código en tu server.php e iniciar el servidor. Normalmente, como estoy usando Windows que agrega más de la lucha, ejecuto el servidor a través de este comando -> php server.php start

Bueno, si estás usando xampp. Aquí hay una forma de hacerlo. Ve a donde quieras poner tus archivos. En nuestro caso, vamos a poner los archivos en

C: /xampp/htdocs/websocket/server.php

C: /xampp/htdocs/websocket/client.php o client.html

Suponiendo que ya tiene esos archivos en su servidor local. Abra su Git Bash o línea de comando o terminal o lo que esté utilizando y descargue las bibliotecas php aquí.

https://github.com/walkor/Workerman

https://github.com/walkor/phpsocket.io

Por lo general, lo descargo a través del compositor y simplemente autocargo esos archivos en mis scripts php.

Y también mira este. ¡Esto es realmente importante ! Necesita esta biblioteca de JavaScript para que client.php o client.html se comuniquen con el server.php cuando lo ejecute.

https://github.com/walkor/phpsocket.io/tree/master/examples/chat/public/socket.io-client

Simplemente copié y pegué esa carpeta socket.io-client en el mismo nivel que mi server.php y mi client.php

Aquí está el código fuente server.php

<?php
require __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;
use PHPSocketIO\SocketIO;

// listen port 2021 for socket.io client
$io = new SocketIO(2021);
$io->on('connection', function($socket)use($io){
    $socket->on('send message', function($msg)use($io){
        $io->emit('new message', $msg);
    });
});

Worker::runAll();

Y aquí está el código fuente client.php o client.html

<!DOCTYPE html>
<html>
    <head>
        <title>Chat</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">        
    </head>
    <body>
        <div id="chat-messages" style="overflow-y: scroll; height: 100px; "></div>        
        <input type="text" class="message">
    </body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>    
    <script src="socket.io-client/socket.io.js"></script>  
    <script>
            var socket = io.connect("ws://127.0.0.1:2021");

            $('.message').on('change', function(){
                socket.emit('send message', $(this).val());
                $(this).val('');
            });

            socket.on('new message', function(data){
                $('#chat-messages').append('<p>' + data +'</p>');
            });
    </script>
</html>

Una vez más, abra su línea de comando o git bash o terminal donde coloca su archivo server.php. Entonces, en nuestro caso, eso es C: / xampp / htdocs / websocket / y escribió php server.php start y presione enter.

Luego vaya a su navegador y escriba http: //localhost/websocket/client.php para visitar su sitio. Luego, escriba cualquier cosa en ese cuadro de texto y verá un php websocket básico sobre la marcha.

Usted sólo tiene que recordar. En la programación de sockets web, solo necesita un servidor y un cliente. Ejecute primero el código del servidor y abra el código del cliente. ¡Y ahí lo tienes! ¡Espero que esto ayude!

por lo tanto
fuente
3

Qué tal esto ? PHPSocketio ?? Es una alternativa del lado del servidor socket.io php. El bucle de eventos se basa en la extensión de eventos pecl. Aunque no lo he probado hasta ahora.

Sankalp Singha
fuente
3

Ahora estamos en 2018 y hoola, hay una manera de implementar WS y WAMPServer en php. Se llama Ratchet .

shamaseen
fuente
0

Estaba buscando una forma realmente simple de hacer que PHP envíe un mensaje socket.io a los clientes.

Esto no requiere ninguna biblioteca PHP adicional, solo usa sockets.

En lugar de intentar conectarse a la interfaz websocket como tantas otras soluciones, simplemente conéctese al servidor node.js y úselo .on('data')para recibir el mensaje.

Luego, socket.iopuede reenviarlo a los clientes.

Detecta una conexión desde tu servidor PHP en Node.js así:

//You might have something like this - just included to show object setup
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

server.on("connection", function(s) {
    //If connection is from our server (localhost)
    if(s.remoteAddress == "::ffff:127.0.0.1") {
        s.on('data', function(buf) {
            var js = JSON.parse(buf);
            io.emit(js.msg,js.data); //Send the msg to socket.io clients
        });
    }
});

Aquí está el código php increíblemente simple: lo envolví en una función, puede encontrar algo mejor.

Tenga en cuenta que ese 8080es el puerto para mi servidor Node.js; es posible que desee cambiarlo.

function sio_message($message, $data) {
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    $result = socket_connect($socket, '127.0.0.1', 8080);
    if(!$result) {
        die('cannot connect '.socket_strerror(socket_last_error()).PHP_EOL);
    }
    $bytes = socket_write($socket, json_encode(Array("msg" => $message, "data" => $data)));
    socket_close($socket);
}

Puedes usarlo así:

sio_message("chat message","Hello from PHP!");

También puede enviar matrices que se convierten a json y se pasan a los clientes.

sio_message("DataUpdate",Array("Data1" => "something", "Data2" => "something else"));

Esta es una forma útil de "confiar" en que sus clientes reciben mensajes legítimos del servidor.

También puede hacer que PHP pase las actualizaciones de la base de datos sin que cientos de clientes consulten la base de datos.

Desearía haber encontrado esto antes, ¡espero que esto ayude! 😉

usuario1274820
fuente
1
Buena idea, ¡estaba buscando una forma de saltarme los redis (si es una buena idea)! Hay un error tipográfico en el primer código, un punto y coma después s.remoteAddress;. Sin embargo, no lo estoy haciendo funcionar. Obtengo la conexión en el nodo, detecta la conexión, la dirección remota es correcta, pero s.on('data')nunca sucede, pero no pasa nada. Yo s.on('msg')también lo intenté . Estoy usando tu código PHP exacto. Estoy usando https, para el servidor de nodo, pero eso no debería importar?
Niclas
@Niclas oye, perdón por el error tipográfico, no puedo creer que haya estado ahí todo el tiempo. ¿Su servidor de nodo se está ejecutando en el puerto 8080? Si no, necesita cambiar el puerto. Si es así, verifique Remote Addressque se devuelve, asegúrese de que sea la dirección local / de bucle invertido, puede ser diferente con la configuración de su servidor. Para probar, puede eliminar la líneaif(s.remoteAddress == "::ffff:127.0.0.1")
usuario1274820
¡Gracias por la rápida respuesta! Logré exitosamente console.log hasta el final, incluso la dirección remota tenía razón, simplemente no entra en la sección s.on ('datos'). ¿Hay alguna forma de probar qué mensaje se envió? Vuelva a leer mi comentario para ver si me perdí algo. Podría comenzar esto como una nueva pregunta para publicar el código, pero es casi exactamente como el suyo.
Niclas
Comencé esto como una nueva pregunta para facilitar el debate en detalle: stackoverflow.com/questions/53689391/…
Niclas