php如何實現基於事件驅動的網絡編程

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);
相關文章
相關標籤/搜索