php
如何實現基於事件驅動的網絡編程當客戶端發送數據到服務端,服務端返回相同信息。php
保持鏈接編程
說明
接下來的全部代碼僅用於簡單的小demo
生產環境須要考慮代碼的嚴謹性。bash
簡單的接受數據並返回網絡
<?php $socket = stream_socket_server("tcp://0.0.0.0:8000"); $conn = stream_socket_accept($socket); $info = fgets($conn,1024); fwrite($conn, $info."\n"); ?>
$ telnet 0.0.0.0 8000 Trying 0.0.0.0... Connected to 0.0.0.0. Escape character is '^]'. hello //客戶端輸入 hello //這個是服務端回顯的 Connection closed by foreign host.
上面的例子中,服務端在接收到客戶端數據後會返回相同信息,而後鏈接會被關閉。沒法保持鏈接。?。socket
$socket = stream_socket_server("tcp://0.0.0.0:8000"); while($conn = stream_socket_accept($socket)){ while($info = fread($conn,1024)){ fwrite($conn,$info); } }
上面的例子
簡單的接受數據並返回
保持運行
缺點是同時只能處理一個鏈接!!!!!?tcp
$socket = stream_socket_server("tcp://0.0.0.0:8000"); while($conn = stream_socket_accept($socket)){ if(pcntl_fork()){ while($info = fread($conn,1024)){ fwrite($conn,$info); } } }
這裏實際上fork了n個子進程去處理n個請求。
可是使用fork進程的方式很差,很很差。
若是10萬個鏈接,豈不是要10萬個進程???oh,no!!oop
基於libevent的實現,很完美!!!?code
<?php $server = stream_socket_server("tcp://0.0.0.0:8000"); $event = event_new(); $base = event_base_new(); $events = []; event_set($event,$server,EV_READ|EV_PERSIST,function()use($server){ global $base,$events; $conn = stream_socket_accept($server); $event = event_new(); event_set($event,$conn,EV_READ|EV_PERSIST,function()use($conn){ $info = fread($conn,1024); if(strlen($info)>0){ fwrite($conn,$info); } }); event_base_set($event,$base); event_add($event); $events[] = $event; }); event_base_set($event,$base); event_add($event); event_base_loop($base);