Używanie PHP z Socket.io

128

Czy można używać Sockets.io po stronie klienta i komunikować się z aplikacją opartą na PHP na serwerze? Czy PHP obsługuje w ogóle taki sposób pisania kodu „długotrwałe połączenie”?

Cały przykładowy kod, który znalazłem dla socket.io, wydaje się dotyczyć node.js po stronie serwera, więc nie ma tam żadnej pomocy.

Yuvi
źródło
3
Możliwy duplikat: Socket.io ze źródła php
hakre
Możesz rozważyć tylko popychacz. Ma fajną bibliotekę PHP, której będę używać.
Devin G Rhode
cześć, spróbuj tego - github.com/walkor/phpsocket.io
Zhenya Hristova

Odpowiedzi:

98

Odpowiedź na to pytanie może być trochę za późno, ale oto co znalazłem.

Nie chcę dyskutować o tym, że węzły robią to lepiej niż php, czy nie, nie o to chodzi.

Rozwiązanie jest takie: nie znalazłem żadnej implementacji socket.io dla PHP.

Ale jest kilka sposobów implementacji WebSockets . Istnieje ta wtyczka jQuery, która umożliwia korzystanie z Websockets, jednocześnie łagodnie degradując dla nieobsługujących przeglądarek. Po stronie PHP istnieje klasa, która wydaje się być najczęściej używana dla serwerów PHP WS.

Florian Margaine
źródło
1
klasa phpwebsocket jest rzeczywiście właściwą drogą, jeśli chcesz implementację serwera websocket php. Jednak nie jest to związane z pytaniem. OP ma już zaimplementowany serwer WS (socket.io) i poprosił o sposoby komunikacji z aplikacją php.
kasper Taeymans
72

Jeśli chcesz używać socket.io razem z php, to może być twoja odpowiedź!

witryna projektu:

elephant.io

są też na githubie:

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

Elephant.io dostarcza klienta socket.io w pełni napisanego w PHP, który powinien być używany w całym projekcie.

Jest to lekka i łatwa w użyciu biblioteka, której celem jest wprowadzenie funkcjonalności w czasie rzeczywistym do aplikacji PHP poprzez socket.io i websockets w celu wykonania działań, których nie można wykonać w pełnym javascript.

przykład ze strony projektu (komunikacja z serwerem websocket przez php)

serwer 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`';

serwer z gniazdem io

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
źródło
2
Dam Ci tutaj +1, ale wygląda na to, że wciąż niewiele brakuje do użycia w środowisku produkcyjnym.
Beachhouse
17
Widziałem to, ale jedna rzecz mnie zdezorientowała. Czy nie chodzi o to, aby PHP zaimplementowało serwer sockets.io? zamiast tego Elepant.io wydaje się być implementacją PHP klienta sockets.io, dla którego można połączyć się z innym serwerem sockets.io (co oznacza, że ​​elephant.io nie nasłuchuje połączeń od klientów sockets.io, łącząc do nich i ich obsługi)?
Pimp Trizkit
Właśnie tego szukałem, szkoda, że ​​trwałe połączenie jest na wczesnym etapie rozwoju.
slezadav
8
Cześć wszystkim. Celem Elephant.io jest po prostu odpalanie zdarzeń z PHP na serwer socket.io. Nie otwierać trwałego połączenia. Ale żeby móc szybko łączyć się i wysyłać zdarzenia / wiadomości. Używamy go w produkcji i działa jak urok.
guillaumepotier
3
ta biblioteka nie jest już utrzymywana i ma dla nas pewne problemy
Flion
14

Jeśli naprawdę chcesz używać PHP jako zaplecza dla socket.io, oto co znalazłem. Alternatywa dla dwóch serwerów php socket.io po stronie serwera.

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

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

Przykładowe kody dla pierwszego repozytorium takiego jak to.

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
źródło
7

Do „długotrwałego połączenia”, o którym wspomniałeś, możesz użyć Ratchet for PHP. Jest to biblioteka zbudowana w oparciu o funkcje Stream Socket, które PHP obsługuje od PHP 5.

Po stronie klienta musisz użyć protokołu WebSocket obsługiwanego przez HTML5 zamiast Socket.io (ponieważ wiesz, socket.io działa tylko z node.js).

Jeśli nadal chcesz używać Socket.io, możesz spróbować w ten sposób: - znajdź i pobierz socket.io.js dla klienta do użytku - pracuj z Ratchet, aby zasymulować sposób, w jaki socket.io robi na serwerze

Mam nadzieję że to pomoże!

Chung Xa
źródło
6

Erm, dlaczego miałbyś chcieć? Pozostaw PHP na zapleczu i NodeJS / Sockets, aby robić swoje nieblokujące rzeczy.

Oto coś, od czego możesz zacząć: http://groups.google.com/group/socket_io/browse_thread/thread/74a76896d2b72ccc

Osobiście pracuję ekspresowo z punktem końcowym, który nasłuchuje bezpośrednio interakcji z PHP.

Na przykład, jeśli wysłałem użytkownikowi wiadomość e-mail, chcę, aby socket.io wyświetlał powiadomienie w czasie rzeczywistym dla użytkownika.

Chcesz interakcji z socket.io do php, możesz po prostu zrobić coś takiego:

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();  

Poważnie, PHP jest świetne do robienia rzeczy po stronie serwera i niech będzie z połączeniami, dla których nie ma teraz miejsca w tej domenie. Po co robić długie odpytywanie, skoro masz gniazda sieciowe lub flashsockets.

PaulM
źródło
32
Ponieważ niektórzy z nas są w stanie zdobyć tylko tani host, który pozwoli ci używać tylko php i mysql.
Lanbo
31
Ponieważ niektórzy z nas muszą pracować z istniejącymi frameworkami, które zależą od PHP. Na przykład opracowujemy i sprzedajemy skrypt PHP, ale chcielibyśmy ulepszyć komunikator internetowy za pomocą websockets, nie chcemy pisać wszystkich awaryjnych, które socket.io już zaimplementował, ale nie możemy wymagać NodeJS od naszych klientów.
Purefan
3
@PaulM: Wypróbowałem kilku dostawców VPS za <10 USD i wszystkie te są naprawdę do niczego. Każdy był bardzo powolny, gdy coś się zepsuło, wsparcie jest okropne itp. Z drugiej strony w Finlandii nie jest rzadkością uzyskanie przyzwoitej jakości hostingu (ale tylko z plikami php / mysql / static) z subskrypcją adsl, bez dodatkowych opłat . Więc nie, możliwość kupienia gównianego VPS za 5 USD zdecydowanie nie jest rozwiązaniem.
Olli
4
Dla dostawców VPS za <10 USD jedynym przyzwoitym, jaki do tej pory znalazłem, jest digitalocean.com. Ale ten jest całkiem niezły.
Aeolun,
3
Nie zgadzam się. Myślę, że taka odpowiedź jest bardzo istotna. Ktoś, kto powie Ci, że „źle go używasz”, może być o wiele więcej wart niż ktoś, kto pomoże Ci w niewłaściwym użyciu.
Rijk,
6

Znam walczącego człowieka! Ale ostatnio prawie pracowałem z Workermanem. Jeśli nie natknąłeś się na ten framework php, lepiej to sprawdź!

Cóż, Workerman jest asynchronicznym, sterowanym zdarzeniami frameworkiem PHP do łatwego tworzenia szybkich, skalowalnych aplikacji sieciowych. (Właśnie skopiowałem i wkleiłem to z ich strony internetowej hahahah http://www.workerman.net/en/ )

Prostym sposobem na wyjaśnienie tego jest to, że jeśli chodzi o programowanie za pomocą gniazda sieciowego, wszystko, czego naprawdę potrzebujesz, to mieć 2 pliki na serwerze lub serwerze lokalnym (gdziekolwiek pracujesz).

  1. server.php (kod źródłowy, który odpowie na wszystkie żądania klienta)

  2. client.php / client.html (kod źródłowy, który wykona żądane rzeczy)

Więc w zasadzie najpierw poprawiasz kod na swoim server.php i uruchamiasz serwer. Zwykle, ponieważ używam systemu Windows, który dodaje więcej trudności, uruchamiam serwer za pomocą tego polecenia -> php server.php start

Cóż, jeśli używasz Xampp. Oto jeden sposób, aby to zrobić. Idź tam, gdzie chcesz umieścić swoje pliki. W naszym przypadku zamierzamy umieścić pliki

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

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

Zakładając, że masz już te pliki na swoim lokalnym serwerze. Otwórz swój Git Bash, wiersz poleceń lub terminal lub cokolwiek, z którego korzystasz i pobierz biblioteki php tutaj.

https://github.com/walkor/Workerman

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

Zwykle pobieram go przez kompozytora i po prostu automatycznie ładuję te pliki w moich skryptach php.

A także sprawdź ten. To jest naprawdę ważne ! Potrzebujesz tej biblioteki javascript, aby twój client.php lub client.html komunikował się z server.php po uruchomieniu.

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

Po prostu skopiowałem i wkleiłem ten folder socket.io-client na tym samym poziomie co mój server.php i mój client.php

Tutaj jest kod źródłowy 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();

A oto kod źródłowy client.php lub 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>

Jeszcze raz otwórz wiersz poleceń, git bash lub terminal, w którym umieściłeś plik server.php. Więc w naszym przypadku jest to C: / xampp / htdocs / websocket / i wpisaliśmy php server.php start i naciśnij enter.

Następnie przejdź do przeglądarki i wpisz http: //localhost/websocket/client.php, aby odwiedzić swoją witrynę. Następnie po prostu wpisz cokolwiek do tego pola tekstowego, a zobaczysz podstawowe gniazdo php w podróży!

Musisz tylko pamiętać. W programowaniu gniazd sieciowych wystarczy serwer i klient. Najpierw uruchom kod serwera, a następnie otwórz kod klienta. I masz to! Mam nadzieję że to pomoże!

tamaladrain
źródło
4

Jeśli naprawdę chcesz używać PHP jako zaplecza dla WebSockets, te linki mogą Cię poprowadzić:

https://github.com/lemmingzshadow/php-websocket

http://www.htmlgoodies.com/html5/other/create-a-bi-directional-connection-to-a-php-server-using-html5-websockets.html#fbid=QqpDVi8FqD9

Chris Hanson
źródło
1
Dzięki temu możesz używać socket.io (ze wszystkimi obsługiwanymi transportami i przeglądarkami). A może musisz użyć klienta, który jest dostarczany z php-websocket?
Darren Cook
3

Co powiesz na to ? PHPSocketio ?? Jest to alternatywa dla serwera php socket.io po stronie serwera. Pętla zdarzeń jest oparta na rozszerzeniu zdarzenia pecl. Chociaż do tej pory sam tego nie próbowałem.

Sankalp Singha
źródło
3

Jesteśmy teraz w 2018 roku i hoola, jest sposób na zaimplementowanie WS i WAMPServer na php. Nazywa się Ratchet .

shamaseen
źródło
0

Szukałem naprawdę prostego sposobu, aby PHP wysłał wiadomość socket.io do klientów.

Nie wymaga to żadnych dodatkowych bibliotek PHP - po prostu używa gniazd.

Zamiast próbować połączyć się z interfejsem WebSocket, jak w przypadku wielu innych rozwiązań, po prostu połącz się z serwerem node.js i użyj go, .on('data')aby odebrać wiadomość.

Następnie socket.iomożesz przekazać go klientom.

Wykryj połączenie z serwera PHP w Node.js w następujący sposób:

//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
        });
    }
});

Oto niesamowicie prosty kod php - opakowałem go w funkcję - możesz wymyślić coś lepszego.

Zauważ, że 8080jest to port do mojego serwera Node.js - możesz chcieć zmienić.

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);
}

Możesz go używać w ten sposób:

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

Możesz także wysyłać tablice, które są konwertowane na json i przekazywane klientom.

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

Jest to przydatny sposób „zaufania”, że Twoi klienci otrzymują prawidłowe wiadomości z serwera.

Możesz również pozwolić PHP przekazywać aktualizacje bazy danych bez konieczności wysyłania setek klientów do bazy danych.

Żałuję, że nie znalazłem tego wcześniej - mam nadzieję, że to pomoże! 😉

user1274820
źródło
1
Niezły pomysł, szukałem sposobu, aby ominąć redis (jeśli to dobry pomysł)! W pierwszym kodzie jest literówka, a po nim średnik s.remoteAddress;. Jednak nie udaje mi się to. Otrzymuję połączenie w węźle, wykrywa połączenie, zdalnyadres jest poprawny, ale s.on('data')nigdy się nie dzieje, ale nic się nie dzieje. Ja s.on('msg')też próbowałem . Używam twojego dokładnego kodu PHP. Używam protokołu https jako serwera węzłów, ale to nie powinno mieć znaczenia?
Niclas,
@Niclas hej, przepraszam za literówkę - nie mogę uwierzyć, że to było przez cały czas. Czy serwer węzła działa na porcie 8080? Jeśli nie, musisz zmienić port. Jeśli tak, sprawdź, Remote Addressktóry jest zwracany - upewnij się, że jest to adres zwrotny / lokalny - może być inny w przypadku konfiguracji serwera. Do testowania możesz usunąć wierszif(s.remoteAddress == "::ffff:127.0.0.1")
user1274820,
Dziękuję za szybką odpowiedź! Zrobiłem pomyślnie console.log całą drogę, nawet zdalny adres był poprawny, po prostu nie wchodzi do sekcji s.on ('data'). Czy istnieje sposób sprawdzenia, jaka wiadomość została wysłana? Przeczytaj ponownie mój komentarz, aby sprawdzić, czy coś nie przeoczyłem. Mogę zacząć to od nowego pytania do opublikowania kodu, ale jest prawie dokładnie takie samo jak twoje.
Niclas,
Zacząłem od nowego pytania, aby ułatwić szczegółowe omówienie: stackoverflow.com/questions/53689391/ ...
Niclas