swoole server跟client

知識點

一、Swoole-server介紹php

二、建立一個Tcp serverreact

三、swoole驅動模式及相應事件nginx

  4serverclient交互web

  5、同步client跟異步clientapache

  6tcp的特色及粘包處理編程

1、server

    server,顧名思義,就是服務。咱們平時接觸比較多的無非就是nginx和apache。做爲webServer,兩者都是經過監聽某端口對外提供服務,swoole的server也不例外一樣須要綁定端口,同時可以提供給客戶端相關的服務瀏覽器

1.1建立一個server對象服務器

    建立server的步驟:swoole

           1、實例化Server對象網絡

           2、設置運行時參數

           3、註冊事件回調函數

           4、啓動服務器

 

 

 

 

 示例:

 

 

 
   

   server的建立,只須要綁定要監聽的ip和端口,若是ip指定爲127.0.0.1,則表示客戶端只能位於本機才能鏈接,其餘計算機沒法鏈接,若是須要全部的客戶端都能鏈接則能夠設置0.0.0.0

 


端口這裏指定爲9501,能夠經過netstat查看下該端口是否被佔用。若是該端口被佔用,可更改成其餘端口,如9502,9503等。

 

2.2、配置

  在享受swoole的server以前,一樣咱們須要配置一下server,好比調幾我的來提供服務(幾個進程),以及是不是後臺執行(守護進程)等等一些其它的配置。

 這個就須要咱們作一些配置了,可是並不是像fpm直接在文件內配置,咱們能夠在server建立後,經過set方法指定配置項。

 同時,這個配置項也有不少,好比說咱們能夠指定日誌文件記錄具體的錯誤信息等等,你均可以在官網的手冊上尋找有哪些配置項,咱們也會在貫穿swoole的同時講解一部分經常使用的配置項。

這裏咱們首要說明一下worker進程數的配置,由於swoole是多進程的異步服務器因此須要設置工做進程數,提高服務器性能。

 

 

 

 

咱們能夠指定配置項worker_num等於某個正整數。這個正整數設置多少合適,即我要開多少個worker進程處理們的業務邏輯纔好呢我?官方建議咱們設置爲CPU核數的1-4倍。由於咱們開的進程越多,內存的佔用也就更多,進程間切換也就須要耗費更多的資源。咱們這裏設置開啓兩個worker進程。默認該參數的值等於你機器的CPU核數。 

 

 

2.3事件驅動

swoole另一個比較吸引人的地方,就是swoole_server是事件驅動的。咱們在使用的過程當中不須要關注底層是怎麼實現的,底層是C寫的php只是作了個傳遞的做用因此只須要對底層相應的動做註冊相應的回調,在回調函數中處理業務邏輯便可。

什麼意思呢?我舉個例子:

你啓動了一個server,當客戶端鏈接的時候(觸發事件),你不須要關心它是怎麼鏈接的,你就單純的註冊一個connect函數,作一些鏈接後的業務處理便可(執行業務)相似於js的事件監聽,好比觸發了click事件,就會執行相應的閉包。

Swoole監聽的事件:

 

 

讓咱們來看看幾種常見的事件回調。

 

 
   

參數$serv是咱們一開始建立的swoole_server對象,

參數$fd是惟一標識,用於區分不一樣的客戶端,同時該參數是1-1600萬之間能夠複用的整數。簡單解釋下複用:假設如今客戶端一、二、3處於鏈接中,客戶端4要鏈接的話$fd就是4,可是不巧的是客戶端3鏈接不穩定,斷掉了,客戶端4鏈接到server的話,$fd就是3,這樣看的話。

 

1600W個鏈接夠用嗎?單機業務百萬鏈接,已是很厲害了,不用擔憂

監聽客戶端數據發送,觸發回調

 

 

 

 

worker進程內觸發的。第三個參數$fromId指的是哪個reactor線程,具體咱們會在多進程模型當中詳細分析,先忽略。。

 

咱們看第四個參數,這個參數就是服務端接受到的數據,注意是字符串或者二進制內容,注意咱們在Receive回調內,調用了$serv的send方法,咱們可使用send方法,向client發起通知。

 

監聽客戶端關閉,觸發回調

 

 

這個很簡單,當客戶端關閉,或者服務端主動關閉鏈接的時候會觸發。

到此呢,咱們基本上已經搭建到了一個高性能的server固然,很是簡單,下面咱們只須要調用start方法啓動server便可

 

 

 

因爲swoole_server只能運行在CLI模式下,因此不要試圖經過瀏覽器進行訪問,有據說過apache是基於nginx運行的嗎,你們地位相同,只能配合,沒有上下關係

 

咱們在命令行下面執行,自行去鏈接,這裏不補充基礎知識,tese.php就是剛剛服務器的方法

 

 

 

咱們平時執行完一個指令,執行完就結束了,可是如今的狀況正好相反,當前程序一直處於執行中的狀態,並無退出終端。同時由於swooleserver是常駐內存運行的,因此若是

修改了代碼,須要ctrl+c中斷,從新運行才行。

 

在咱們第一步初始化server所填寫的ip和端口嗎,也就是說server如今正在監聽9501端口提供服務。

當前終端暫時不動,咱們新開一個終端,查看端口發現確實如此。

 

 

 

server啓動好了能幹什麼呢?常見的網絡編程模式都是client-server的,也就是說咱們還須要模擬一個客戶端與之交互。

 

2、同步client跟異步client

 默認的swooleserver是能夠提供tcp/udp  socket請求協議,而後根據請求數據,執行相應的邏輯

 

PHP中,咱們經常使用socket函數來建立TCP鏈接,用CURL庫來建立Http鏈接。一樣的,爲了簡化操做,Swoole也提供了一樣的Client類用於實現客戶端的功能,而且增長了異步非阻塞的模式,讓用戶在客戶端也能使用事件循環。

 

swoole_client的構造函數以下所示:

swoole_client->__construct($sock_type,SWOOLE_SOCK_SYNC, $key);

 

 

第一個參數:

SWOOLE_SOCK_TCP 建立tcp socket
SWOOLE_SOCK_TCP6 建立tcp ipv6 socket
SWOOLE_SOCK_UDP 建立udp socket
SWOOLE_SOCK_UDP6 建立udp ipv6 socket

 

第二個參數表示是同步仍是異步
SWOOLE_SOCK_SYNC 同步客戶端
SWOOLE_SOCK_ASYNC 異步客戶端

第三個參數(暫不瞭解)

用於長鏈接的Key,默認使用IP:PORT做爲key。相同key的鏈接會被複用

什麼是網絡協議?

網絡協議爲計算機網絡中進行數據交換而創建的規則、標準或約定的集合

2.1 TCPUDP介紹

一、TCP面向鏈接(如打電話要先撥號創建鏈接);UDP是無鏈接的,即發送數據以前不須要創建鏈接

2TCP提供可靠的服務。也就是說,經過TCP鏈接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付

3tcp經過校驗和,重傳控制,序號標識,滑動窗口、確認應答實現可靠傳輸。如丟包時的重發控制,還能夠對次序亂掉的分包進行順序控制。

3UDP具備較好的實時性,工做效率比TCP高,適用於對高速傳輸和實時性有較高的通訊或廣播通訊。

4TCP對系統資源要求較多,UDP對系統資源要求較少。

 

 

 

 

 2.2、新建一個同步客戶端

    代碼如圖所示:

 

 

同步client是同步阻塞的。一整套connect->send()->rev()->close()是同步進行的。若是須要大量的數據處理,後臺不能在規定的時間內返回數據會致使接收超時,而且由於是同步執行因此須要等待後臺數據的返回。

 

2.3同步異步概念

swoole是既支持全異步,也支持同步,同步跟異步的概念,咱們須要瞭解

 

同步與異步的重點在消息通知的方式上,也就是調用結果通知的方式。 

同步: 當一個同步調用發出去後,調用者要一直等待調用結果的通知後,才能進行後續的執行。 


異步:當一個異步調用發出去後,調用者不能當即獲得調用結果的返回。 

 

 

生活中的例子:

同步買奶茶:小明點單交錢,而後等着拿奶茶;

異步買奶茶:小明點單交錢,店員給小明一個小票,等小明奶茶作好了,再來取。

 

2.4異步客戶端

當設定swoole_client爲異步模式後,swoole_client就不能使用recv方法了,而須要經過on方法提供指定的回調函數,而後在回調函數當中處理,也就是小明等待奶茶作好了異步通知,消息發送跟接收並非同步運行的。

 

 

 

2.5 實戰案例  

       客戶端設備發送一個請求,服務端接收,根據業務邏輯的需求服務端A須要發送一個請求到服務端B獲取數據,再返回給服務端A,服務端A返回給客戶端A

 

服務端A既是客戶端也是服務器,服務端A要發送請求到服務端B,而後服務端B返回消息給服務端A

 

 

3、tcp粘包處理

TCP通訊特色
1. TCP 是流式協議沒有消息邊界,客戶端向服務器端發送一次數據,可能會被服務器端分紅屢次收到。客戶端向服務器端發送多少數據。服務器端可能一次所有收到。
2.保證傳輸的可靠性,順序。
3.TCP擁有擁塞控制,因此數據包可能會延後發送。

 

沒有消息邊界:

能夠理解爲水在一個水管裏的流動,咱們不知道哪段數據是一個咱們須要的完整數據

 

收發有緩衝區:

好比:當水從一端流到了另外一端,咱們在收數據的時候,不可能每來一滴水就處理一次,這個緩衝區就至關於有了一個水桶,再接了必定的水以後內核再給數據交到用戶空間,這樣能夠大大提高性能。

 

2.1什麼是 TCP 粘包?

TCP 粘包是指發送方發送的若干包數據  接收方接收時粘成一包,從接收緩衝區看,後一包數據的頭緊接着前一包數據的尾。

2.2 TCP 出現粘包的緣由?

發送方:發送方須要等緩衝區滿才發送出去,形成粘包

接收方:接收方不及時接收緩衝區的包,形成多個包接收

 

模擬下產生問題的場景,下面的結果確實是出現了粘包的問題

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.3 Swoole怎麼處理粘包

2.3.1EOF 結束協議

經過約定結束符,來肯定包數據是否發送完畢

開啓open_eof_check=true,並用package_eof來設置一個完整數據結尾字符,同時設置自動拆分open_eof_split

 

舉個例子:

 

 

 

注意:

一、要保證業務數據裏不能出現package_eof設置的字符,不然將致使數據錯誤了。

2、能夠手動拆包,去掉open_eof_split,自行 explode("\r\n", $data),而後循環發送

  

2.3.2 固定包頭+包體協議

這種方式也很是常見,原理是經過約定數據流的前幾個字節來表示一個完整的數據有多長,從第一個數據到達以後,先經過讀取固定的幾個字節,解出數據包的長度,而後按這個長度繼續取出後面的數據,依次循環。

 

案例:

 

 

 

相關配置:

open_length_check:打開包長檢測特性

package_length_type:長度字段的類型,固定包頭中用一個4字節或2字節表示包體長度。

package_length_offset:從第幾個字節開始是長度,好比包頭長度爲120字節,第10個字節爲長度值,這裏填入9(從0開始計數)

package_body_offset:從第幾個字節開始計算長度,好比包頭爲長度爲120字節,第10個字節爲長度值,包體長度爲1000。若是長度包含包頭,這裏填入0,若是不包含包頭,這裏填入120

package_max_length:最大容許的包長度。由於在一個請求包完整接收前,須要將全部數據保存在內存中,因此須要作保護。避免內存佔用過大。

 

 

package_length_type 長度值的類型

長度值的類型,接受一個字符參數,與phppack函數一致。目前swoole支持10種類型:

c:有符號、1字節

C:無符號、1字節

s:有符號、主機字節序、2字節

S:無符號、主機字節序、2字節

n:無符號、網絡字節序、2字節 (經常使用)

N:無符號、網絡字節序、4字節 (經常使用)

l:有符號、主機字節序、4字節(小寫L

L:無符號、主機字節序、4字節(大寫L

v:無符號、小端字節序、2字節

V:無符號、小端字節序、4字節

相關文章
相關標籤/搜索