PHP Socket長連接的應用

一、什麼是PHP Socket長連接

Socket是一個抽象層,它允許程序在網絡環境中發送和接收數據。使用Socket時,程序將創建一個Socket對象,並用它來代表一個網絡連接,可以發送數據和接收數據。

在PHP中,通過socket擴展可以很方便地使用Socket API,實現TCP/UDP協議的通信。其中,PHP Socket長連接指建立Socket連接後,長時間保持連接狀態,能夠發送多個請求和接收多個數據包,以及服務器在一段時間沒有數據包傳輸時自動關閉連接。

二、PHP Socket長連接的優點

1、降低網絡連接時延:長連接可以避免頻繁地建立和斷開網絡連接,減少網絡連接的時延。

2、減輕服務器資源壓力:在每個連接間產生的握手協議、安全協議、重複發送的HTTP頭必須消耗額外的帶寬和享元模式,通過長連接可以減少網絡開銷,減輕服務器壓力。

3、隱藏網絡延遲:使用長連接可以減少網絡開銷,緩存請求在服務端的答覆,避免一次沒有完全填充的請求等待下一次完整的請求。從而有效地將網絡延遲隱藏在網絡背景中,提高用戶體驗。

三、PHP Socket長連接的應用

1、聊天室

我們可以使用PHP Socket長連接來實現聊天室功能。當用戶在網頁上輸入聊天內容後,客戶端將該內容以Socket長連接方式發送到後台,並放入消息隊列中,服務端讀取消息隊列並再次發送給所有的聊天室用戶。


//PHP長連接服務端代碼示例
set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, "0.0.0.0", 9999);
socket_listen($sock);
$clients = array($sock);
while (true) {
    $read = $clients;
    $write = null;
    $err = null;
    if (socket_select($read, $write, $err, 5) < 1) {
        continue;
    }
    if (in_array($sock, $read)) {
        $clients[] = $newsock = socket_accept($sock);
        $header = PHP_EOL.'Welcome to chat-demo'.PHP_EOL.'Enter your name: ';

        @socket_write($newsock, $header, strlen($header));
        unset($read[ array_search( $sock, $read ) ]);
    }
 
    foreach ($read as $read_sock) {
        $data = @socket_read($read_sock, 2048, PHP_NORMAL_READ);
        if ($data === false) {
            socket_close($read_sock);
            $key_to_remove = array_search($read_sock, $clients, true);
            unset($clients[$key_to_remove]);
            break;
        }
        $data = trim($data);
        if (!empty($data)) {
            foreach ($clients as $send_sock) {
                if ($send_sock == $sock || $send_sock == $read_sock){
                    continue;
                }
                @socket_write($send_sock, $data, strlen($data));
            }
        }
    }
}

2、即時通訊

使用PHP Socket長連接可以實現即時通訊功能。比如,客戶端可以將用戶輸入的文本消息以及相關的用戶信息,通過Socket長連接方式提交到服務器端,服務器端收到後可以通過Websocket將消息推送給所有需要的在線用戶。


//PHP長連接服務端代碼示例
set_time_limit(0);
error_reporting(E_ALL & ~E_NOTICE);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 9999);
socket_listen($socket);

$clients = array();
while (true) {
    $read = $clients; 
    $read[] = $socket;

    socket_select($read, $write, $except, null);

    foreach ($read as $connect_socket) {
        if ($connect_socket == $socket) { 
            $new_socket = socket_accept($connect_socket);
            if ($new_socket) {
                $clients[] = $new_socket;
            }
        } else {
            $bytes = @socket_recv($connect_socket, $buffer, 1024, MSG_DONTWAIT);
            if ($bytes) {
                if (preg_match('/(.*): (.*)/', $buffer, $matches) == 1) {
                    $name = $matches[1];
                    $message = $matches[2];
                    $response = $name . ':' . $message . "\n";
                } else {
                    $response = "robot: " . $buffer;
                }

                foreach ($clients as $client) {
                    @socket_write($client, $response, strlen($response));
                }
            }
            if ($bytes === false) {
                $key_to_remove = array_search($connect_socket, $clients, true);
                unset($clients[$key_to_remove]);
                socket_shutdown($connect_socket, 2);
                socket_close($connect_socket);
            }
        }
    }
}

3、定時器

PHP中沒有自帶的「計時器」功能,但使用Socket長連接可以輕鬆實現定時器功能。當需要創建一個任務,在指定的時間間隔內運行該任務時,可以在客戶端啟動Socket服務端程序,並在連接建立後開啟一個周期性的定時器。這樣,在一定時間後,服務端程序會主動調用客戶端指定的函數。


//PHP長連接客戶端代碼示例
set_time_limit(0);
$host = 'localhost';
$port = 2345;
$conn = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (socket_connect($conn, $host, $port) === false) {
    die("ERROR: " . socket_strerror(socket_last_error()) . "\n");
}

$next_call_time = time();

while (true) {
    $time_left = $next_call_time - time();
    if ($time_left > 0) {
        usleep(1000000 * $time_left);
    }
    $next_call_time += 5;
    socket_write($conn, 'time to do something ...');
}

四、總結

PHP Socket長連接可以有效地緩解網絡延遲、減少服務器資源壓力,具有很多實際應用場景。上述示例演示了使用PHP Socket長連接實現聊天室、即時通訊、定時器等功能的方法。如需使用PHP Socket長連接應用到您的項目中,可以參考以上示例代碼,根據實際情況進行調整和擴展。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/250504.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-13 13:28
下一篇 2024-12-13 13:29

相關推薦

  • PHP和Python哪個好找工作?

    PHP和Python都是非常流行的編程語言,它們被廣泛應用於不同領域的開發中。但是,在考慮擇業方向的時候,很多人都會有一個問題:PHP和Python哪個好找工作?這篇文章將從多個方…

    編程 2025-04-29
  • PHP怎麼接幣

    想要在自己的網站或應用中接受比特幣等加密貨幣的支付,就需要對該加密貨幣擁有一定的了解,並使用對應的API進行開發。本文將從多個方面詳細闡述如何使用PHP接受加密貨幣的支付。 一、環…

    編程 2025-04-29
  • Python中使用socket傳輸圖片

    本文將從多個方面介紹如何使用Python中的socket模塊傳輸圖片,涉及到準備工作、發送方部分和接收方部分的詳細代碼實現。 一、準備工作 在使用Python中的socket模塊進…

    編程 2025-04-28
  • 使用PHP foreach遍歷有相同屬性的值

    本篇文章將介紹如何使用PHP foreach遍歷具有相同屬性的值,並給出相應的代碼示例。 一、基礎概念 在講解如何使用PHP foreach遍歷有相同屬性的值之前,我們需要先了解幾…

    編程 2025-04-28
  • Python Socket阻塞問題的解析

    本文將從多個方面對Python socket阻塞問題進行詳細闡述,包括阻塞的原因、影響、解決方法等等。 一、阻塞的原因 阻塞是指在等待某個事件的過程中,該進程無法處理其他任務,直到…

    編程 2025-04-27
  • PHP獲取301跳轉後的地址

    本文將為大家介紹如何使用PHP獲取301跳轉後的地址。301重定向是什麼呢?當我們訪問一個網頁A,但是它已經被遷移到了另一個地址B,此時若服務器端做了301重定向,那麼你的瀏覽器在…

    編程 2025-04-27
  • PHP登錄頁面代碼實現

    本文將從多個方面詳細闡述如何使用PHP編寫一個簡單的登錄頁面。 1. PHP登錄頁面基本架構 在PHP登錄頁面中,需要包含HTML表單,用戶在表單中輸入賬號密碼等信息,提交表單後服…

    編程 2025-04-27
  • C# Socket關閉後客戶端仍可連接的解決方法

    對於C# Socket通信中的一些問題,多數人可能已經熟知,但是有些問題仍然困擾着一部分人,例如Socket關閉後,客戶端仍然可以連接。本篇文章將在此問題為中心,圍繞該問題的原因和…

    編程 2025-04-27
  • PHP與Python的比較

    本文將會對PHP與Python進行比較和對比分析,包括語法特性、優缺點等方面。幫助讀者更好地理解和使用這兩種語言。 一、語法特性 PHP語法特性: <?php // 簡單的P…

    編程 2025-04-27
  • PHP版本管理工具phpenv詳解

    在PHP項目開發過程中,我們可能需要用到不同版本的PHP環境來試驗不同的功能或避免不同版本的兼容性問題。或者我們需要在同一台服務器上同時運行多個不同版本的PHP語言。但是每次手動安…

    編程 2025-04-24

發表回復

登錄後才能評論