Comet és server-push
2009-09-01T21:28:54+02:00
2009-09-09T11:21:24+02:00
2022-07-19T04:44:08+02:00
  • sziasztok!

    php socketes témában találtam ezt a dolgot ami sztem elég jó. állítólag jó sok klienst elbír. el is indul frankón.

    mi kellene ahhoz hogy ezzel menjen egy chat? a streamhub-os chat-et sztetek össze lehetne hozni ezzel?

    van egy olyan érzésem hogy innen már nem lehet olyan nehéz erre rátolni egy rendkívül egyszerű chat-szerű valamit.
    Mutasd a teljes hozzászólást!
  • no.

    a két probléma közül (bejelentkezés mysql userrel valamint a másik) az utóbbi dologgal kapcsolatban kimódoltam a következőt:

    a divnek a tartalmát sztem létre tudom hozni simán php-val hogy ilyen legyen:

    <div id="chatMessages">
    <table>
    <tr><td>Client-1252220066733:</td><td id=1252220066733>online</td></tr>
    <tr><td>Client-1252220066734:</td><td id=1252220066734>online</td></tr>
    <tr><td>Client-1252220066735:</td><td id=1252220066735>online</td></tr>
    </table>
    </div>

    ha jól értelmezem, akkor ez a funkció:

    function chatUpdated(topic, data)
    {
    var div = document.createElement("DIV");
    div.innerHTML = data.client + ": " + data.message;
    document.getElementById('chatMessages').appendChild(div);
    }

    mindig létrehoz egy újabb divet, aztán beleteszi a fő div-be, hozzátoldva a többihez. namost ha én ezt átírom erre:

    function chatUpdated(topic, data)
    {
    $('1252220066734').update('busy');
    $('1252220066734').innerHTML;
    }

    amihez a prototype framework kell, akkor a listámban beupdate-eli a megfelelő td értékét.

    nem tudom ez gond-e (mármint hogy két ilyen cucc van):

    <head>
    <script src="streamhub-min.js"></script>
    <script src="prototype-1.6.0.3.js"></script>
    </head>

    lényeg, hogy elvileg ezzel megoldottam az egyik részét, ami ezek szerint a könnyebbik volt. ha ezek után meg tudom csinálni azt hogy belépéskor megkapjam a mysql userid-met akkor azt valahogy csak bele tudom gyömöszölni az update funkcióba. és akkor kész van amit akartam.

    namost ezen a nyomon is elindultam már, csak azt nem tudom, illetve sztem úgy van, hogy miután a .java-t javac-ztem és létrejött a class, utána már a .java-t nem is használja a program, ugyanis hiába írtam át a .java-ban a client.getUid() részt bármire, ugyanúgy működött minden.

    na ez az egy kemény diónak látszik mert jelenleg egy random számot kap minden frissítéskor a böngésző. ezt kéne kikerülni valahogy.

    de várjunk csak! miért is kellene nekem ebből a javaból kikérni bármilyen id-t? tőlem létrehozhatja, egyszerűen nem kérem ki hanem a sajátomat amit simán php-val visszakaptam bejelentkezéskor, azt teszem be.

    tkp. megoldottam.

    most hogy mennyire elegáns stb azon lehet vitatkozni de úgy hogy igazábol abszolút nem értek a témához mégis meg tudtam csinálni, nekem határozottan fülig ér a szám.
    Mutasd a teljes hozzászólást!
  • öröm látni hogy magyarországon ennyi segítőkész ember van

    köszi

    most már csakazértis megcsinálom.
    Mutasd a teljes hozzászólást!
  • Latom szeretsz monologalni!

    reménytelen. ezt én az életben nem fogom tudni megcsinálni.


    Na vegre!
    Mutasd a teljes hozzászólást!
  • azért ez így még mindig abszolút nem egyszerű (legalábbis nekem).

    minden user pl kap egy egyedi azonosítót. ez már megint olyan kellemetlen. ez is olyan adat, amit célszerű lenne adatbázisban tárolni, és mindig oda lyukadok ki, hogy miért nincs a mysql-php-apache-nak erre egy kiforrott, egyszerű megoldása, ami mindjárt az adatbázisban található userekkel oldaná meg a dolgot.

    most valahogy még azt is ki kellene találnom, hogy hogyan fogom ezt a chat dolgot úgy összehozni, hogy egy bejeltkező (és az adatbázisban létező) felhasználót jelenítsen meg... reménytelen. ezt én az életben nem fogom tudni megcsinálni.
    Mutasd a teljes hozzászólást!
  • [itt] azt olvasom hogy nem fog menni amit gondoltam. érkeznek ugye az üzenetek. ez mind javascript változó formájában gondolom:

    <html>
    <head>
    <title>Comet Chat</title>
    <script src="streamhub-min.js"></script>
    </head>
    <body>
    <input type="button" id="online" value="online" onclick="online()">

    <div id="chatMessages"></div>
    <script>

    function chatUpdated(topic, data)
    {
    var div = document.createElement("DIV");
    div.innerHTML = data.client + ": " + data.message;
    document.getElementById('chatMessages').appendChild(div);
    }

    function online()
    {
    var message = document.getElementById('online').value;
    var json = "{'message':'" + escapeQuotes(message) + "'}";
    hub.publish("chat", json);
    }

    function escapeQuotes(sString)
    {
    return sString.replace(/(\')/gi, "\\$1").replace(/(\\\\\')/gi, "\\'");
    }

    var hub = new StreamHub();
    hub.connect("http://localhost:10000/");
    hub.subscribe("chat", chatUpdated);
    </script>

    </body>
    </html>

    azt szeretném elérni hogy ha megnyomta a user az online gombot, amiről saját maga is kap egy értesítést, akkor egy if-be betenni hogy amennyiben stimmel a user, akkor az a gomb, amelyinek az id-je vagy value-ja megegyezik az üzenettel, legyen disabled. javascripthez nem nagyon értek de addig is amíg valaki esetleg segít, én is keresem hogyan tudnám megoldani.

    megvan: piszokegyszerűen működik:
    <input type="button" id="online" value="online" onclick="online(); this.disabled=true; document.getElementById('busy').disabled=false">

    jó de igazábol a probléma továbbra is fennáll, hiszen majd szeretnék egy user listát, aminek dinamikusan kéne változni annak függvényében hogy valaki be- vagy kijelentkezett-e vagy állapotot váltott. tehát valahogy lekérdezném kezdésnél az adatbázisbol hogy ki van online, és azoknak mi a pontos státusza (nezavarj, elfoglalt, stb.). ez adna egy php listát, amit annak függvényében kellene változtatnom, hogy milyen üzenetek érkeznek erről a comet csatornárol. tehát kéne tudnom valahogy php által is kezelni a javascriptes változókat, ami ha a fenti linket jól értelmeztem, nem lehetséges anélkül hogy el ne küldeném újra az infot GET-tel vagy POST-tal a szervernek. ez gond. akkor nem marad más mint valami mással megoldani a lekérdezést, és ez praktikusan javascript lehetne ha tud ilyet. na ennek utánanézek.
    Mutasd a teljes hozzászólást!
  • nahh, nagy nehezen működik. el se hiszem... jöhet a következő lépés.

    nahh, működik a chat is. elvileg ezzel képesnek kell lennem arra amit el szerettem volna érni. vagyis, textboxba irogatás helyett csak egy gomb megnyomásával küldeni egy üzenetet az állapotomról. és persze párhuzamosan az adatbázisba is letárolni hogy éppen ki milyen állapotban van, így mindig meglesz az utolsó állapota a felhasználóknak, és bejelentkezés után elsőnek ez lesz lekérdezve, de ha menet közben történik valami változás akkor arról azonnal kapnak a többiek változást. így elmondva egyszerűen hangzik, de aztán nagyon könnyen lehet hogy még meggyűlik a bajom ezzel is.
    Mutasd a teljes hozzászólást!
  • sztem nem jó [ez] a leírás a
    Getting Started with StreamHub and Comet
    -ről.

    ugyanis ott van ez az addStaticContent rész ami egy könyvtárat határoz meg, de előbb indította el a szervert mielőtt még betette volna...
    Mutasd a teljes hozzászólást!
  • most meg megpróbáltam a streamhub-ot feltenni, úgy néz ki jó is, csak nem indítja el (nem találja) az index.html-t.

    a leírást 100x átolvastam már persze idegességemben lehet hogy még mindig nem veszek észre valamit, de erre felfigyeltem:

    Using addStaticContentDir we will make the HelloWorld folder available via the Comet server. Setting the file to "." means we're adding the current directory.


    ennek evidensnek kéne lenni hogy ez mit jelent vagy hogy hogyan kell megcsinálni? csak azért mert az egész neten sehol nincs ilyen kifejezés, és a file-okban sincs, és ilyen file sincs. de valszeg ezzel lehet a gond, ez megmagyarázná miért nem találja az index.html-t (amit mellesleg már mindenhova megpróbáltam betenni).

    ami érdekes, az az, hogy van egy ilyen parancs:

    java -cp examples\lib\jar\streamhub-2.0.4.jar;examples\lib\jar\streamhub-java-adapter-sdk-2.0.4.jar;examples\lib\jar\json-20080701.jar;examples\lib\jar\log4j-1.2.14.jar DemoRunner


    ezt egy könyvtárban találtam, egy RunExamples.bat nevű parancsban van benne és ha így indítom el, akkor lát egy index oldalt, csak nem azt amit nekem első indításkor minden további nélkül látnom kéne... tényleg nagyszerűen egyszerű az egész.

    áhh! olyan van file-okba hogy addStaticContent!
    Mutasd a teljes hozzászólást!
  • már miért is menne
    Mutasd a teljes hozzászólást!
  • ja látom hogy kell neki jdk is.
    hát nem valami fényes a jetty telepítése, egy csomó csomagot nem tud letölteni...
    meg már egy fél órája töltöget...
    hogy ezeket a dolgokat miért nem lehetett mindjárt a telepítőbe belecsomagolni...
    na mindegy csak menjen.

    most úgy néz ki elindult. nem tudom amiket nem tudott leszedni azokat gondolom megpróbálta mégegyszer, remélem azért minden lejött ami kellett.

    lehet hogy nem:

    Error 404 - Not Found.
    No context on this server matched or handled this request.
    Contexts known to this server are:
    /xxxxxx ---> org.mortbay.jetty.plugin.Jetty6PluginWebAppContext@139ef3a{/xxxxxx,file:/c:/Program Files/Apache Software Foundation/jetty-6.1.20/contrib/cometd/demo/src/main/webapp/;jar:file:/C:/Documents and Settings/stargazer/.m2/repository/org/cometd/javascript/cometd-javascript-dojo/1.0.0rc0/cometd-javascript-dojo-1.0.0rc0.war!/;jar:file:/C:/Documents and Settings/stargazer/.m2/repository/org/cometd/javascript/cometd-javascript-jquery/1.0.0rc0/cometd-javascript-jquery-1.0.0rc0.war!/;jar:file:/C:/Documents and Settings/stargazer/.m2/repository/org/cometd/javascript/cometd-examples-dojo/1.0.0rc0/cometd-examples-dojo-1.0.0rc0.war!/;jar:file:/C:/Documents and Settings/stargazer/.m2/repository/org/cometd/javascript/cometd-examples-jquery/1.0.0rc0/cometd-examples-jquery-1.0.0rc0.war!/;}
    Mutasd a teljes hozzászólást!
  • Javac egy fordito, maven egy build tool, amely a forditast egy kulso forditoval vegzi.
    Mutasd a teljes hozzászólást!
  • az ezen az oldalon található leírásban szereplő maven helyett használható javac is?
    Mutasd a teljes hozzászólást!
  • egyszerűen nem működik. pedig nagyon úgy érzem hogy egy hajszál választ el az áttöréstől. komolyan valahol itt van az orrom előtt csak egy fától nem látom az erdőt.

    sztem valami gond van a socket_write()-tal a szerver oldalon, ugyanis telnet esetén sem kapok visszajelzést. addig hiába is akarok böngészőben.

    az fwrite az működik, szépen mutatja a szervernél a cli hogy érkezett input és echozza hogy mit küldött ki, de sztem azt nem küldi vissza valamiért.

    a kliens oldalán egyszerű a történet mint a szög, hiszen egy fgets-et használnak mindenhol és ennyi az egész. úgyhogy azzal nem lehet gond.

    illetve érdekes mert a welcome msg az megy, pedig ugyanolyan socket_write-nak tűnik, nem látok különbséget és érdekes azt kiírja a telnetnél ahogy belépek. ezt nem értem hogy miért van annyi a különbség hogy az egyik do {} while ()-on belül van, de tuti hogy bemegy abba az ágba, mert az echo ami szintén ott van az megy.

    komolyan az agyam készen van nagyon hogy úgy érzem annyira primitív az egész annyira mennie kéne, és egyszerűen nem.

    bakker: működik. valami. még nem tudom pontosan mi történt, de most jónak tűnik.

    természetesen nem a socket_write-tal volt a gond, hanem a socket_read-del.
    $input = socket_read($spawn, 1024, 1);
    helyett
    $input = socket_read($spawn, 1024, PHP_NORMAL_READ);
    raktam be.

    tehát. most működik, úgy, hogy amit berakok fwrite-ba, azt vissza is adja a böngésző is, de továbbra is gond hogy a while miatt ugye egyfolytában homokórázik amíg ki nem timeout-ol. ezt kéne valahogy elkerülni következő lépésként.

    az jutott eszembe, elég sok helyen használnak egyszerű dolgok megoldására sqlite-ot. mivel nekem ez a socket téma csak arra kéne hogy nagyon kevés és egyszerű adatokat tároljak és sugározzak, nem lehet hogy valami sqlite vagy ehhez hasonló dologgal a php jobban pariban van ilyen értesítő funkciók terén, mint pl az említett ms sql notification services?
    Mutasd a teljes hozzászólást!
  • tehát:

    #!C:/wamp/bin/php/php5.3.0/php.exe &#8211;q
    <?php

    error_reporting(E_ALL);

    set_time_limit(0);
    ob_implicit_flush();

    $address = '127.0.0.1';
    $port = 10000;

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

    socket_bind($sock, $address, $port);

    socket_listen($sock, 5);

    do
    {
    $msgsock = socket_accept($sock);

    $msg = "\nWelcome to the PHP Test Server. \n".
    "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($msgsock, $msg, strlen($msg));

    do
    {
    $buf = socket_read($msgsock, 2048, PHP_NORMAL_READ);

    if (!$buf = trim($buf))
    {
    continue;
    }

    if ($buf == 'quit')
    {
    break;
    }

    if ($buf == 'shutdown')
    {
    socket_close($msgsock);
    break 2;
    }

    $talkback = "PHP: You said '$buf'.\n";
    socket_write($msgsock, $talkback, strlen($talkback));
    //echo "$buf\n"; // ez a szervernél echozza a dolgokat a cli-nél
    } while (true);
    socket_close($msgsock);
    } while (true);

    socket_close($sock);

    ?>

    ez a dolog működik.

    a devshed.com-on találtam egy példát arra hogyan lehet klienst csinálni.

    <?php

    $host="127.0.0.1";
    $port = 10000;

    $fp = fsockopen ($host, $port, $errno, $errstr);

    fgets ($fp, 1024);

    $message= "hello world!";

    fputs ($fp, $message);

    $result .= fgets ($fp, 1024);

    fputs ($fp, "quit");
    fclose ($fp);

    echo "Server said: ":$result;

    ?>

    ezt hoztam ki belőle. ezzel már azt elértem, hogy a szerver welcome message megjelenik, de valamiért ez mindjárt hazavágja a szervert és elkezdei 1000-rel nyomatni hogy
    "php warning: socket_read(): unable to read from socket[0]: an existing connection was forcibly closed by the remote host. on line 28"


    a 28-as sor pedig ez:
    $buf = socket_read($msgsock, 2048, PHP_NORMAL_READ);

    a kliensnél futó fclose() bezárja a szerver portját? ez elég buta dolog lenne. azt hittem ez csak a saját kacsolatát zárja le. ha quit-et nyomok telneten, az nem vágja haza a szervert. és ha kiszedem a fputs ($fp, "quit");-et akkor is hazavágja.

    most nem tudom mi a frász van, ennek jónak kéne lenni. írja a devshedes szerver hogy bejövő kapcsolat, meg kérés, és a böngésző csak homokórázik míg ki nem timeout-ol...
    Mutasd a teljes hozzászólást!
  • tehát a php.net-es socket szerver példa működik, egyelőre egy klienssel, és azt is csak telnettel tudom használni.

    itt találtam egy példát arra hogyan lehet rácupanni egy socket szerver egyik portjára php klienssel. hát homokórázik, homokórázik, amíg le nem lövöm a szervert, akkor kiechozza amit gondolt. pedig a szerver scriptben is benne van hogy ob_implicit_flush(); meg a kliensbe is betettem már kínomban pedig sztem erős lenne ha mindkettőbe kellene (de lehet).
    Mutasd a teljes hozzászólást!
  • értem.

    de akkor hogy lehet hogy itt ez:

    $ telnet 192.168.1.99 1234
    Trying 192.168.1.99...
    Connected to medusa.
    Escape character is '^]'.
    jack and the beanstalk
    klatsnaeb eht dna kcaj (fordítottját küldi vissza)
    Connection closed by foreign host.

    működik. lehet hogy azért mert ez mondjuk linux? és ott picit másképp működik?

    különben puttyal ment már nekem összetettebb példa socket server is, ami vissza tudta küldözgetni amiket beírtam, csak az annyival volt bonyolultabb hogy már nem értettem ki kivel van. most szeretnék egyszer ádám-évátol elindulni hogy megértsem a dolog lényegét.

    igen ez működik jól és még értem is nagyjábol.
    ezt az egyet nem értem benne:

    if (!$buf = trim($buf))
    {
    continue;
    }
    Mutasd a teljes hozzászólást!
  • A socket_read() alapesetben, így ahogy használod annyit fog olvasni, amennyi adat a rendelkezésére áll, de maximum a megadott számú karaktert (tehát lehet kevesebb is, csak több nem). Ha te telnettel pötyögsz, akkor ott minden beírt karakter külön el lesz küldve, s a socket_read()-ed máris kiolvassa és visszatér az eredménnyel. Ha már PHP, nézd meg a dokumentáció példáit is: Socket examples
    Mutasd a teljes hozzászólást!
  • A socket server-t nem a kliens hívja meg url-lel, hanem parancssorból futtatják (php cli), tehát a script_time_out nem vonatkozik rá. Viszont ingyenes szerveren 99,9%, hogy egy ilyet nem lehet futtatni.


    Így van, mint ahogy én is pontosan ezt írtam

    PHP szolgáltatásai socket-ek terén simán felveszik a versenyt a c/c++-szal, teljesítményben sincs lyan nagy különbség.


    Nem kifejezetten a C/C++-ra gondoltam, inkább a többire. Másrészt nem is csak az alap lehetőségeket kell nézni, hanem azt is, hogy tkp. az említett nyelvek mindegyikéhez lehet könnyen találni olyan könyvtárat, amivel megspórolható a 0-ról való fejlesztés, s kész, letesztelt, optimalizált, nagyteljesítményű eszközöket biztosít saját alkalmazások fejlesztéséhez (pl. Apache Mina, stb.), míg PHP-ra ez nemigen jellemző.
    Mutasd a teljes hozzászólást!
  • A socket server-t nem a kliens hívja meg url-lel, hanem parancssorból futtatják (php cli), tehát a script_time_out nem vonatkozik rá. Viszont ingyenes szerveren 99,9%, hogy egy ilyet nem lehet futtatni. PHP szolgáltatásai socket-ek terén simán felveszik a versenyt a c/c++-szal, teljesítményben sincs lyan nagy különbség.
    Mutasd a teljes hozzászólást!
  • oké értem. az a helyzet hogy egyelőre csak a php-t ismerem. és ha úgy is van hogy mindenképp meg kell tanulnom mást is ha ezt össze akarom hozni, akkor meg fogom, de akkor is előbb meg kell értenem a php-ből kiindulva.

    nekem egy sztem rendkívül egyszerű dologra kell ez csak, semmi komoly szándékom nincs vele. illetve nekem nagyon komoly és fontos lenne hogy működjön. gyakorlatilag a neten található példák mind egy kaptafára mennek:

    #!C:/wamp/bin/php/php5.3.0/php.exe -q
    <?php

    set_time_limit(0);

    $address = "127.0.0.1";
    $port = "10000";

    $sock = socket_create(AF_INET, SOCK_STREAM, 0);

    socket_bind($sock, $address, $port);

    socket_listen($sock, 5);

    $client = socket_accept($sock);

    $input = socket_read($client, 1024);
    $output = "thanks for connecting, you wrote: ".$input."\r\n";

    socket_write($client, $output);

    socket_close($client);

    socket_close($sock);

    ?>

    ez az. van egy kis problémám vele, ti az hogy puttyal alapbol nem is tudok rácsatlakozni, azonnal eldobja magát, és ha telnettel csinálom, akkor megy, de csak egyetlen leütést fogad el, pedig a példák szerint ennek el kéne fogadnia több karakternyi adatot is. ahogy megnyomom az egyik billentyűt, mondjuk a "h" betűt, azonnal visszadobja hogy thanks for connecting, you wrote: h és bontja.
    Mutasd a teljes hozzászólást!
  • Egy socket szervernek akkor van értelme, ha folyamatosan fut. Namost ehhez nem úgy kell futtatni egy programot, hogy jön egy HTTP kérés, majd a webszerver elkezd futtatni erre egy PHP scriptet (és most tekintsünk el tőle, hogy engedélyezve van-e egyáltalán a szerveren a socket-használat), ami vagy futhat a végtelenségig, ha a beállított időkorlát engedi vagy nem, hanem rendes önálló alkalmazásként. És ez az, amit egy sima tárhelyen nem fogsz megtenni. Természetesen PHP programokat is lehet futtatni a wbeszervertől függetlenül (CLI), de ha már erre van lehetőséged, akkor sokkal jobban jársz, ha nem PHP-ban készíted azt a socket szervert, mert nem kifejezetten erre való, a szolgáltatásainak kínálata és a teljesítmény szempontjából sem - sokkal inkább Java, .NET, C/C++, stb. Kliensnek pedig webes kliens esetén szóba jöhet a Flash, a Silverlight és a Java applet, más nemigen.
    Mutasd a teljes hozzászólást!
  • A socket technológia alkalmazását kliens oldalon manapság legegyszerűbben flash segítségével oldják meg.


    Meg javascript, meg java applet, meg silverlight. Egyik se nehezebb, mint a flash.
    Mutasd a teljes hozzászólást!
  • tehát akkor a socket-eknél is játszik ez a max_execution_time dolog? akkor ez azt jeleti hogy ezzel is folyamatosan homokóriázik majd a böngésző?
    Mutasd a teljes hozzászólást!
  • Mert a socket() fuggvenyek startbol tiltva vannak, es a max_execution_time is eleg alacsony...
    Mutasd a teljes hozzászólást!
  • de különben miért nem lehet?
    Mutasd a teljes hozzászólást!
  • ez privát szerver lenne.
    Mutasd a teljes hozzászólást!
  • PHP-s socket servert ingyenes tarhelyen nem fogsz futtatni, ezt uge vagod..?
    Mutasd a teljes hozzászólást!
  • most azt szeretném valahogy elérni majd hogy a naten található nagyon egyszerű egyszerhasználatos socket szerver példák és a nekem egyelőre túl bonyolultak között megtaláljam az arany középutat hogy ne bontsa a kapcsolatot olyan hamar, és utána csinálni egy böngésző kliens szkriptet ami perzisztens socket kapcsolatot épít ki és megjeleníti a szerverhez érkező adatokat, valamint hogy böngészőn keresztül tudjak küldeni is a szervernek olyan inputot amit aztán vissza tud küldeni. úgy érzem hogy nyomon vagyok.
    Mutasd a teljes hozzászólást!
  • rájöttem: két php.ini van és amit a systray-ből lehet variálni, az nem jó.

    no ez mind szép és jó, már ott futosgál a socket szerver, de miért mindenhol cli-ből meg telnettel vacakolnak vele. ennek az a legfőbb ételme ha böngészőből lehet valahogy interaktivizálni magunknak. sehol nem találok erre okos és egyszerű példát...
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd