Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] Stałe połączenie z serwerem
kamil4u
post
Post #1





Grupa: Zarejestrowani
Postów: 2 350
Pomógł: 512
Dołączył: 4.01.2009
Skąd: Wrocław / Świdnica

Ostrzeżenie: (0%)
-----


Witam.

Potrzebuję nawiązać stałe połączenie z serwerem, niestety wszelkie moje próby spełzły na niczym.

Robię konsolę, która umożliwi mi wysłanie i otrzymywanie danych z serwera. Idea działania jest taka:
Kod
connect 192.163.0.153 500 <-- połączenie z serwerem o ip 92.163.0.153 - port 500
-- connection set
send 123456 <-- wysłanie danych do serwera 123456
-- 654321 <-- odpowiedź serwera


Wszystkie ip, porty czy dane na forum są fikcyjne.

Problem polega na tym, że każde polecenie( connect, send) to nowe zapytanie do serwera(PHP) przez AJAX. Gdy mój kod PHP wygląda mniej więcej tak:
  1. <?php
  2. if( isset($_POST['name']) && !empty($_POST['name']) ){
  3. $name = $_POST['name']; // $name to nazwa funkcji <-> connect, send
  4.  
  5. if( isset($_POST['data']) && !empty($_POST['data']) )
  6. $data = $_POST['data']; //$data to parametry np. dla connect w powyższym przykładzie będzie to ciąg: '192.163.0.153,500'
  7.  
  8. require_once('./klasa.php');
  9.  
  10. switch( $name ){
  11. case 'connect':
  12. $data = explode( ',',$data );
  13. $connection = klasa::connect( $data[0],$data[1] );
  14. if( $connection ){
  15. $_SESSION['connection'] = $connection; //!!!
  16. echo 'connection set';
  17. } else
  18. echo 'error: connection lost';
  19. break;
  20.  
  21. case 'send':
  22. $fp = $_SESSION['connection']; //!!!
  23.  
  24. $zmienna = explode(',',$data);
  25. var_dump( $_SESSION['connection'] ); //wyświetla zawsze 0
  26.  
  27. //różnego rodzaju operacje
  28. fgets($fp, $zmienna);
  29. $x = fread($fp, 8192);
  30.  
  31. echo $x;
  32. break;
  33.  
  34. default:
  35. break;
  36. }
  37. }
  38. ?>

Plik klasa.php jest bardzo prosty:
  1. <?php
  2. class klasa{
  3.  
  4. public static function connect( $id,$port ){
  5. $connection = stream_socket_client( 'tcp://'.$id.':'.$port,$errno,$errstr );
  6.  
  7. if( $connection )
  8. return $connection;
  9. else
  10. return false;
  11. }
  12. }
  13. ?>


Jak widać łączę się z serwerem za pomocą stream_socket_client i próbuję utworzone połączenie zapisać w sesji "$_SESSION['connection'] = $connection;". Następnie w kolejnym zapytaniu( AJAX, konsola -> funkcja send) próbuję "odzyskać" to połączenie poprzez "$fp = $_SESSION['connection'];"

Jednak wtedy uzyskuje błąd, że pierwszy parametr w funkcjach fgets i fread jest nieprawidłowy - jak pisałem przyjmuje wartość (int)0.

Próbowałem chyba wszystkiego stream_socket_client, stream_socket_server, fsockopen, pfsockopen, jednak nie udało mi się osiągnąć zamierzonego efektu.

Jak mimo zakończenia działania skryptu PHP utworzyć stałe połączenie z serwerem, które będzie przechowywane w sesji?

Pozdrawiam i z góry dziękuje z odpowiedzi.

PS. Jestem pewien, że sama funkcja send działa prawidłowo.
Go to the top of the page
+Quote Post
Fifi209
post
Post #2





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Zapisz uchwyt do sesji. ;]
Go to the top of the page
+Quote Post
kamil4u
post
Post #3





Grupa: Zarejestrowani
Postów: 2 350
Pomógł: 512
Dołączył: 4.01.2009
Skąd: Wrocław / Świdnica

Ostrzeżenie: (0%)
-----


No, ale przecież tak robię...
  1. Linia 16: $_SESSION['connection'] = $connection; //!!!
  2. Linia 23: $fp = $_SESSION['connection']; //!!!


No chyba, że robię to źle, ale nie wydaje mi się. Moim zdaniem połączenie jest zamykane w chwili zakończenia skryptu PHP i sesja tu nie pomoże.
Funkcja pfsockopen teoretycznie powinna być idealna, ale albo ja nie umiem z niej korzystać, albo nie rozumiem jak działa - wtedy prosiłbym o wytłumaczenie. Próbowałem też w stream_socket_client skorzystać z flagi: STREAM_CLIENT_PERSISTENT ,ale efekt uzyskuje ten sam: w sesji znajduje się wartość: (int) 0.

Zastanawiałem się, że może te funkcje( pfsockopen ) gdzieś na serwerze zapisują informację o otwartym połączeniu i gdy 2 raz wywołam tę samą funkcję, to wtedy połączenie nie jest otwierane na nowo, ale "brane" z tego zapisu - ale nigdzie nie widzę potwierdzenia tych słów, a nie mam za bardzo jak tego sprawdzić...

Proszę o jakieś wskazówki.

--Edit--
Sesje też na pewno działają prawidłowo

--Edit--
Błędy - jak widać potwierdzają to co mówię - w sesji jest (int 0):
Kod
Warning: fgets() expects parameter 1 to be resource, integer given in /var/www/php/console.php on line 29
Warning: fread() expects parameter 1 to be resource, integer given in /var/www/php/console.php on line 30


Ten post edytował kamil4u 9.06.2011, 14:46:35
Go to the top of the page
+Quote Post
wookieb
post
Post #4





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(Fifi209 @ 9.06.2011, 15:11:46 ) *
Zapisz uchwyt do sesji. ;]

Sesja jest serializowana. Resource-y (uchwyty) nie mogą być serializowane. Nic do nie da. Preferowałbym jakiś middleware.
Go to the top of the page
+Quote Post
Kuziu
post
Post #5





Grupa: Zarejestrowani
Postów: 743
Pomógł: 0
Dołączył: 11.11.2003
Skąd: Toruń

Ostrzeżenie: (0%)
-----


Oczywiście że jest zamykane po zakończeniu skryptu, tak to by wisiało mnóstwo połączeń nie zamkniętych.
Go to the top of the page
+Quote Post
Fifi209
post
Post #6





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Kuziu, nikt tu o zamykaniu nic nie pisał tylko o serializacji sesji i o tym, że uchwyty serializowane być nie mogą.
Go to the top of the page
+Quote Post
kamil4u
post
Post #7





Grupa: Zarejestrowani
Postów: 2 350
Pomógł: 512
Dołączył: 4.01.2009
Skąd: Wrocław / Świdnica

Ostrzeżenie: (0%)
-----


A nie można jakoś wymusić niezamknięcia połączenia? Po co są te funkcje, które podałem, skoro jak mniemam "nic nie dają"? Mógłby ktoś napisać na ten temat coś więcej - nigdy nie miałem doświadczenia z takimi połączeniami, a w internecie zbyt dużo informacji nie ma.

Szczególnie chodzi mi o funkcję pfsockopen, gdzie w manualu ,jest napisane: "Open persistent Internet or Unix domain socket connection" - jak z niej skorzystać, abym mógł osiągnąć to co chcę - niekoniecznie musi to być sesja.

@fifi209: ja pisałem (IMG:style_emoticons/default/wink.gif) - "Moim zdaniem połączenie jest zamykane w chwili zakończenia skryptu PHP i sesja tu nie pomoże."

@wookieb: Ale jakie(middleware) ? Jak pisałem mam niewielkie doświadczenie pod tym względem. Przyjmę każdą radę.

Ten post edytował kamil4u 9.06.2011, 15:14:37
Go to the top of the page
+Quote Post
KrzysiekWildfire
post
Post #8





Grupa: Zarejestrowani
Postów: 93
Pomógł: 11
Dołączył: 27.10.2010
Skąd: Kutno/Poznań

Ostrzeżenie: (0%)
-----


Widziałem coś takiego do zarządzania serwerem counter strike'a, z tą różnicą, że tam był (z tego co mi się wydaje) java applet - i chyba jest to najlepsze rozwiązanie w takich sytuacjach.
Go to the top of the page
+Quote Post
kamil4u
post
Post #9





Grupa: Zarejestrowani
Postów: 2 350
Pomógł: 512
Dołączył: 4.01.2009
Skąd: Wrocław / Świdnica

Ostrzeżenie: (0%)
-----


@KrzysiekWildfire: dzięki za odpowiedź, jednak to mi nie pomaga.

Jakby ktoś mi powiedział jak to wszystko działa byłoby super.
Go to the top of the page
+Quote Post
sh3d2
post
Post #10





Grupa: Zarejestrowani
Postów: 34
Pomógł: 11
Dołączył: 10.06.2011
Skąd: świdnica

Ostrzeżenie: (0%)
-----


Cytat(kamil4u @ 9.06.2011, 18:57:05 ) *
Jakby ktoś mi powiedział jak to wszystko działa byłoby super.


Wg mnie (oczywiscie moge sie mylic) jest to tak, ze nie musisz (a nawet nie mozesz - nie jestes w stanie) zapisac hooka jako zmiennej sesyjnej, bo jak ktos wyzej madrze powiedzial, to jest resource.
pfsockopen() czy wszystkich innych p*() uzywasz dokladnie tak samo jak ich "tymczasowych" (bez p) odpowiednikow, php samo za ciebie skorzysta z istniejacego polaczenia (zamiast przy wywolaniu p*() tworzyc nowe) jesli takowe znajdze.

kiedy "nic z tego nie bedzie" znajdziesz tu: http://www.php.net/manual/en/function.pfsockopen.php#76716
pozdrawiam

Ten post edytował sh3d2 10.06.2011, 00:42:08
Go to the top of the page
+Quote Post
kamil4u
post
Post #11





Grupa: Zarejestrowani
Postów: 2 350
Pomógł: 512
Dołączył: 4.01.2009
Skąd: Wrocław / Świdnica

Ostrzeżenie: (0%)
-----


Sprawdziłem, jest tak jak piszesz - wcześniej też się tego "domyślałem", ale nie znalazłem dowodu. Dopiero wczoraj sprawdziłem dokładnie komentarze -. Zacząłem się interesować jak to sprawdzić. W pierwszym komentarzu dano wskazówkę, żeby sprawdzić to za pomocą funkcji ftell. Jako, że nie za bardzo jeszcze się orientuję w tych wszystkich funkcjach( i nie do końca rozumiem, co jest napisane w tych komentarzach - dodając techniczne sprawy + ang zaczynam się gubić (IMG:style_emoticons/default/smile.gif) ), trochę zeszło zanim napisałem kod "udowadniający" to co napisałeś.

Podsumowującpfsockopen działa tak, że przy pierwszym połączeniu nie zamyka go, a żeby "ponownie" zdobyć uchwyt do niego, należy po prostu wywołać jeszcze raz tę funkcję, a PHP "domyśli się", że to połączeni jest już otwarte i tylko zwróci nam uchwyt.

Trzeba pamiętać, że trzeba zamknąć takie połączenie.

Bardzo dziękuję!
Pozdrawiam
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 6.10.2025 - 01:29