天天看點

php語言實作一個可商業化的socket server(一)

前面文章講了怎麼去實作一個可自動接單的雲列印機,其中提到要部署一個tcp server ,今天我們講講用PHP怎麼實作一個可商用的socket server。

為了對大多數人更友好,我們選擇以workerman這個開源架構的基礎上做開發。workerman支援php多程序,這樣有利于在并發連接配接上來以後維護大量的tcp連接配接。

WorkerMan的特性

1、純PHP開發

使用WorkerMan開發的應用程式不依賴php-fpm、apache、nginx這些容器就可以獨立運作。 這使得PHP開發者開發、部署、調試應用程式非常友善。

2、支援PHP多程序

為了充分發揮伺服器多CPU的性能,WorkerMan預設支援多程序多任務。WorkerMan開啟一個主程序和多個子程序對外提供服務, 主程序負責監控子程序,子程序獨自監聽網絡連接配接并接收發送及處理資料,由于程序模型簡單,使得WorkerMan更加穩定,更加高效。

3、支援TCP、UDP

WorkerMan支援TCP和UDP兩種傳輸層協定,隻需要更改一個屬性便可以更換傳輸層協定,業務代碼無需改動。

4、支援長連接配接

很多時候需要PHP應用程式要與用戶端保持長連接配接,比如聊天室、遊戲等,但是傳統的PHP容器(apache、nginx、php-fpm)很難做到這一點。 使用WorkerMan,隻要服務端業務不主動調用關閉連接配接接口,便可以使用PHP長連接配接。WorkerMan單個程序可以支援上萬的并發連接配接,多程序則支援數十萬的甚至百萬并發連接配接。

5、支援各種應用層協定

WorkerMan接口上支援各種應用層協定,包括自定義協定。在WorkerMan中更換協定同樣非常簡單,同樣隻是配置一個字段,協定自動切換,業務代碼零改動,甚至可以開啟多個不同協定的端口,滿足不同的用戶端需求。

6、支援高并發

WorkerMan支援Libevent事件輪詢庫(需要安裝Libevent擴充), 使用Libevent在高并發時性能非常卓越,如果沒有安裝Libevent則使用PHP内置的Select相關系統調用,性能也同樣非常強悍。

7、支援服務平滑重新開機

當需要重新開機服務時(例如釋出版本),我們不希望正在處理使用者請求的程序被立刻終止,更不希望重新開機的那一刻導緻用戶端通訊失敗。WorkerMan提供了平滑重新開機功能,能夠保障服務平滑更新,不影響用戶端的使用。

8、支援檔案更新檢測及自動加載

在開發過程中,我們希望在我們改動代碼後能夠立刻生效,以便檢視結果。WorkerMan提供了FileMonitor檔案監控元件,隻要檔案有更新,WorkerMan會自動運作reload,以便加載新的檔案,使之生效。

9、支援以指定使用者運作子程序

因為子程序是實際處理使用者請求的程序,為了安全考慮,子程序不能有太高的權限,是以WorkerMan支援設定子運作程序運作的使用者,使你的伺服器更加安全。

10、支援對象或者資源永久保持

WorkerMan在運作過程中隻會載入解析一次PHP檔案,然後便常駐記憶體,這使得類及函數聲明、PHP執行環境、符号表等不會重複建立銷毀,這與Web容器下運作的PHP機制是完全不同的。在WorkerMan中,一個程序生命周期内靜态成員或者全局變量在不主動銷毀的情況下是永久保持的,也就是将對象或者連接配接等資源放到全局變量或者類靜态成員中則目前程序的整個生命周期内的所有請求都可以複用。例如隻要單個程序内初始化一次資料庫連接配接,則以後這個程序的所有請求都可以複用這個資料庫連接配接,避免了頻繁連接配接資料庫過程中TCP三向交握、 資料庫權限驗證、斷開連接配接時TCP四次握手的過程,極大的提高了應用程式效率。

11、高性能

由于php檔案從磁盤讀取解析一次後便會常駐記憶體,下次使用時直接使用記憶體中的opcode, 極大的減少了磁盤IO及PHP中請求初始化、建立執行環境、詞法解析、文法解析、編譯opcode、請求關閉等諸多耗時過程, 并且不依賴nginx、apache等容器,少了nginx等容器與PHP通信的開銷,最主要的是資源可以永久保持,不必每次初始化資料庫連接配接等等, 是以使用WorkerMan開發應用程式,性能非常高。

12、支援HHVM

支援在HHVM虛拟機上運作,可成倍提升PHP性能。尤其是在cpu密集運算業務中,性能非常優異。通過實際壓力測試對比,在沒有負載業務的情況下,WorkerMan在HHVM下運作比在Zend PHP5.6運作網絡吞吐量提高了30-80%左右

13、支援分布式部署

14、支援守護程序化

15、支援多端口監聽

16、支援标準輸入輸出重定向

安裝架構

composer install workerman/workerman
           
  • 作業系統之間的差異
workerman從3.5.3版本開始已經能夠同時支援linux系統和windows系統。

1、需要PHP>=5.3.3,并配置好PHP的環境變量。

2、Windows版本的Workerman不依賴任何擴充。

3、安裝使用以及使用限制這裡。

4、由于Workerman在Windows下有諸多使用限制,是以正式環境建議用Linux系統,windows系統僅建議用于開發環境。

  • 環境檢測

Linux使用者可以運作以下腳本檢查本地環境是否滿足WorkerMan要求

如果腳本中全部提示ok,則代表滿足WorkerMan運作環境

第一個Demo

我們使用WebSocket協定對外提供服務

  • 建立ws_test.php檔案
<?php
use Workerman\Worker;
require_once __DIR__ . '/Workerman/Autoloader.php';

// 注意:這裡與上個例子不同,使用的是websocket協定
$ws_worker = new Worker("websocket://0.0.0.0:2000");

// 啟動4個程序對外提供服務
$ws_worker->count = 4;

// 當收到用戶端發來的資料後傳回hello $data給用戶端
$ws_worker->onMessage = function($connection, $data)
{
    // 向用戶端發送hello $data
    $connection->send('hello ' . $data);
};

// 運作worker
Worker::runAll();
           

指令行運作

php ws_test.php start
           

至此,我們的tcp server就已經跑起來了

  • 測試

打開chrome浏覽器,按F12打開調試控制台,在Console一欄輸入(或者把下面代碼放入到html頁面用js運作)

// 假設服務端ip為127.0.0.1
ws = new WebSocket("ws://127.0.0.1:2000");
ws.onopen = function() {
    alert("連接配接成功");
    ws.send('tom');
    alert("給服務端發送一個字元串:tom");
};
ws.onmessage = function(e) {
    alert("收到服務端的消息:" + e.data);
};
           

alert彈出就代表浏覽器和tcp server已經建立連接配接了。我們的第一個php socket server就算完成了

繼續閱讀