中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
【Swoole系列2.2】Http、TCP、UDP服務(wù)

Http、TCP、UDP服務(wù)

其實(shí)在上篇文章中,我們就已經(jīng)運(yùn)行起來了一個(gè) Http 服務(wù),也簡(jiǎn)單地說明了一下使用 Swoole 運(yùn)行起來的服務(wù)與普通的 PHP 開發(fā)有什么區(qū)別。想必你現(xiàn)在會(huì)說這沒什么大不了的呀,這些我們的傳統(tǒng)開發(fā)又不是做不到,而且還更方便一些。在基礎(chǔ)篇章中,我們還不會(huì)看到 Swoole 在性能上的優(yōu)勢(shì),畢竟最基礎(chǔ)的一些服務(wù)搭建還是要先了解清楚的。因此,今天我們將繼續(xù)再深入的講一下 Http 相關(guān)的內(nèi)容以及了解一下 TCP、UDP 服務(wù)在 Swoole 中如何運(yùn)行。

Http

我們還是看看上次的 Http 服務(wù)的代碼。

$http = new Swoole\Http\Server('0.0.0.0'9501);

$http->on('Request'function ($request, $response) {
    echo "接收到了請(qǐng)求", PHP_EOL;
    $response->header('Content-Type''text/html; charset=utf-8');
    $response->end('<h1>Hello Swoole. #' . rand(10009999) . '</h1>');
});

echo "服務(wù)啟動(dòng)", PHP_EOL;
$http->start();

首先,我們實(shí)例化了一個(gè) Server 對(duì)象,在這里我們傳遞了兩個(gè)構(gòu)造函數(shù),一個(gè)是監(jiān)聽的 IP 地址,一個(gè)是端口號(hào)。一般情況下,如果是生產(chǎn)環(huán)境內(nèi)網(wǎng),我們建議使用內(nèi)網(wǎng)的本機(jī) IP ,或者直接就是 127.0.0.1 只允許本機(jī)訪問。但是在我們的測(cè)試過程中,需要在虛擬機(jī)外訪問的話,就需要 0.0.0.0 這樣的監(jiān)聽全部 IP 地址。這一塊相信不用我過多解釋了,Linux 服務(wù)的基本知識(shí),數(shù)據(jù)庫(kù)、Redis、PHP-FPM 什么的都有這樣的配置。

接下來,使用 on() 函數(shù),它是一個(gè)監(jiān)聽函數(shù),用于監(jiān)聽指定的事件。在這里,我們監(jiān)聽的就是 Request 事件,監(jiān)聽到的內(nèi)容將通過回調(diào)函數(shù)的參數(shù)返回,也就是第一個(gè)參數(shù) $request ,然后它還會(huì)帶一個(gè) $response 參數(shù)用于返回響應(yīng)事件。當(dāng)使用 $response 參數(shù)的 end() 方法時(shí),將響應(yīng)輸出指定的內(nèi)容并結(jié)束當(dāng)前的請(qǐng)求。

上述步驟就完成了一次普通的 Http 請(qǐng)求響應(yīng)。

request參數(shù)

接下來,我們嘗試打印一下 $request 參數(shù),看看里面都有什么。

$http->on('Request'function ($request, $response) {
    // .....

    var_dump($request);

    // ....
});

在命令行的輸出中,你會(huì)看到打印的結(jié)果,內(nèi)容非常多。

object(Swoole\Http\Request)#6 (8) {
  ["fd"]=>
  int(1)
  ["header"]=>
  array(7) {
    ["host"]=>
    string(19"192.168.56.133:9501"
    ["connection"]=>
    string(10"keep-alive"
    ["upgrade-insecure-requests"]=>
    string(1"1"
    ["user-agent"]=>
    string(120"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36"
    ["accept"]=>
    string(135"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
    ["accept-encoding"]=>
    string(13"gzip, deflate"
    ["accept-language"]=>
    string(23"zh-CN,zh;q=0.9,en;q=0.8"
  }
  ["server"]=>
  array(10) {
    ["request_method"]=>
    string(3"GET"
    ["request_uri"]=>
    string(1"/"
    ["path_info"]=>
    string(1"/"
    ["request_time"]=>
    int(1639098961)
    ["request_time_float"]=>
    float(1639098961.89757)
    ["server_protocol"]=>
    string(8"HTTP/1.1"
    ["server_port"]=>
    int(9501)
    ["remote_port"]=>
    int(54527)
    ["remote_addr"]=>
    string(12"192.168.56.1"
    ["master_time"]=>
    int(1639098961)
  }
  ["cookie"]=>
  NULL
  ["get"]=>
  NULL
  ["files"]=>
  NULL
  ["post"]=>
  NULL
  ["tmpfiles"]=>
  NULL
}

發(fā)現(xiàn)什么了嗎?有 header、server、cookie、get、post 等內(nèi)容。這些是做什么用的呢?別急,再來測(cè)試一下,你可以嘗試打印一下 $_SERVER、$_REQUEST 等相關(guān)的內(nèi)容。同時(shí)為了方便查看,可以給請(qǐng)求鏈接增加一個(gè) GET 參數(shù),比如說這樣請(qǐng)求:http://192.168.56.133:9501/?a=1 。

$http->on('Request'function ($request, $response) {
    // .....

    var_dump($request);
    var_dump($_REQUEST);
    var_dump($_SERVER);
    // ....
});

在你的命令行中,輸出的結(jié)果應(yīng)該是這樣的。

// $request 輸出
object(Swoole\Http\Request)#6 (8) {
  ["fd"]=>
  int(1)
  ["header"]=>
  array(8) {
    ["host"]=>
    string(19"192.168.56.133:9501"
    ["connection"]=>
    string(10"keep-alive"
    ["cache-control"]=>
    string(9"max-age=0"
    ["upgrade-insecure-requests"]=>
    string(1"1"
    ["user-agent"]=>
    string(120"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36"
    ["accept"]=>
    string(135"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
    ["accept-encoding"]=>
    string(13"gzip, deflate"
    ["accept-language"]=>
    string(23"zh-CN,zh;q=0.9,en;q=0.8"
  }
  ["server"]=>
  array(11) {
    ["query_string"]=>
    string(3"a=1"
    ["request_method"]=>
    string(3"GET"
    ["request_uri"]=>
    string(1"/"
    ["path_info"]=>
    string(1"/"
    ["request_time"]=>
    int(1639099269)
    ["request_time_float"]=>
    float(1639099269.109327)
    ["server_protocol"]=>
    string(8"HTTP/1.1"
    ["server_port"]=>
    int(9501)
    ["remote_port"]=>
    int(54864)
    ["remote_addr"]=>
    string(12"192.168.56.1"
    ["master_time"]=>
    int(1639099269)
  }
  ["cookie"]=>
  NULL
  ["get"]=>
  array(1) {
    ["a"]=>
    string(1"1"
  }
  ["files"]=>
  NULL
  ["post"]=>
  NULL
  ["tmpfiles"]=>
  NULL
}

// $_REQUEST 輸出
array(0) {
}

// $_SERVER 輸出
array(38) {
  ["LC_ALL"]=>
  string(11"en_US.UTF-8"
  ["LS_COLORS"]=>
  string(1779"rs=0:di=38;5;33:ln=38;5;51:mh=00:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=01;05;37;41:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;40:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.zst=38;5;9:*.tzst=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.wim=38;5;9:*.swm=38;5;9:*.dwm=38;5;9:*.esd=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.mjpg=38;5;13:*.mjpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.m4a=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.oga=38;5;45:*.opus=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:"
  ["SSH_CONNECTION"]=>
  string(36"192.168.56.1 54331 192.168.56.133 22"
  ["LANG"]=>
  string(11"zh_CN.UTF-8"
  ["HISTCONTROL"]=>
  string(10"ignoredups"
  ["HOSTNAME"]=>
  string(21"localhost.localdomain"
  ["XDG_SESSION_ID"]=>
  string(1"1"
  ["USER"]=>
  string(4"root"
  ["SELINUX_ROLE_REQUESTED"]=>
  string(0""
  ["PWD"]=>
  string(25"/home/www/2.基礎(chǔ)/source"
  ["HOME"]=>
  string(5"/root"
  ["SSH_CLIENT"]=>
  string(21"192.168.56.1 54331 22"
  ["SELINUX_LEVEL_REQUESTED"]=>
  string(0""
  ["PHP_HOME"]=>
  string(14"/usr/local/php"
  ["SSH_TTY"]=>
  string(10"/dev/pts/0"
  ["MAIL"]=>
  string(20"/var/spool/mail/root"
  ["TERM"]=>
  string(14"xterm-256color"
  ["SHELL"]=>
  string(9"/bin/bash"
  ["SELINUX_USE_CURRENT_RANGE"]=>
  string(0""
  ["SHLVL"]=>
  string(1"1"
  ["LANGUAGE"]=>
  string(11"en_US.UTF-8"
  ["LOGNAME"]=>
  string(4"root"
  ["DBUS_SESSION_BUS_ADDRESS"]=>
  string(25"unix:path=/run/user/0/bus"
  ["XDG_RUNTIME_DIR"]=>
  string(11"/run/user/0"
  ["PATH"]=>
  string(78"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/php/bin:/root/bin"
  ["HISTSIZE"]=>
  string(4"1000"
  ["LESSOPEN"]=>
  string(25"||/usr/bin/lesspipe.sh %s"
  ["OLDPWD"]=>
  string(9"/home/www"
  ["_"]=>
  string(22"/usr/local/php/bin/php"
  ["PHP_SELF"]=>
  string(29"2.2Http、TCP、UDP服務(wù).php"
  ["SCRIPT_NAME"]=>
  string(29"2.2Http、TCP、UDP服務(wù).php"
  ["SCRIPT_FILENAME"]=>
  string(29"2.2Http、TCP、UDP服務(wù).php"
  ["PATH_TRANSLATED"]=>
  string(29"2.2Http、TCP、UDP服務(wù).php"
  ["DOCUMENT_ROOT"]=>
  string(0""
  ["REQUEST_TIME_FLOAT"]=>
  float(1639099267.431116)
  ["REQUEST_TIME"]=>
  int(1639099267)
  ["argv"]=>
  array(1) {
    [0]=>
    string(29"2.2Http、TCP、UDP服務(wù).php"
  }
  ["argc"]=>
  int(1)
}

這一下看出問題所在了嗎?你會(huì)發(fā)現(xiàn) $_REQUEST、$_SERVER 這些之前傳統(tǒng) PHP 中的全局常量都無效了。雖然 $_SERVER 也輸出了內(nèi)容,但是請(qǐng)仔細(xì)看,這里 $_SERVER 輸出的是我們的命令行信息,不是我們請(qǐng)求過來的信息。除了這兩個(gè)之外,$_COOKIE、$_GET、$_POST、$_FILES、$_SESSION 等等都是這種情況。那么這些內(nèi)容要獲取的話從哪里獲取呢?相信大家也都看到了,直接在 $request 參數(shù)中就有我們需要的內(nèi)容。

這一塊又是一個(gè)需要我們轉(zhuǎn)變思維的地方。為什么這些全局變量不能使用了呢?最主要的原因一是進(jìn)程隔離問題,二是常駐進(jìn)程可能會(huì)導(dǎo)致的內(nèi)存泄漏問題。

關(guān)于進(jìn)程隔離問題,我們可以這樣來測(cè)。

$http = new Swoole\Http\Server('0.0.0.0'9501);

$i = 1;

$http->set([
    'worker_num'=>2,
]);

$http->on('Request'function ($request, $response) {
    global $i;
    $response->end($i++);
});

$http->start();

注意我們的 $i 變量是放在監(jiān)聽函數(shù)外部的,它是一個(gè)針對(duì)當(dāng)前 PHP 文件的全局變量。之后我們?cè)O(shè)置當(dāng)前服務(wù)的 worker_num ,它的意思是啟用兩個(gè) Worker 進(jìn)程,其實(shí)也就是我們的工作進(jìn)程。

啟動(dòng)服務(wù)后可以查看當(dāng)前的進(jìn)程信息,可以看到有四條 php 進(jìn)程,其中第一個(gè)是主進(jìn)程,剩下三個(gè)是子進(jìn)程,在子進(jìn)程中,還有一個(gè)管理進(jìn)程,最后兩個(gè)就是我們創(chuàng)建的兩個(gè) Worker 進(jìn)程。

[root@localhost ~]# ps -ef | grep php
root      1675  1400  0 22:19 pts/0    00:00:00 php 2.2Http、TCP、UDP服務(wù).php
root      1676  1675  0 22:19 pts/0    00:00:00 php 2.2Http、TCP、UDP服務(wù).php
root      1678  1676  0 22:19 pts/0    00:00:00 php 2.2Http、TCP、UDP服務(wù).php
root      1679  1676  0 22:19 pts/0    00:00:00 php 2.2Http、TCP、UDP服務(wù).php

接下來,開兩個(gè)不同的瀏覽器訪問吧,看看 $i 的輸出會(huì)怎么樣。是不是兩個(gè)瀏覽器刷新的時(shí)候 $i 沒有同步地增加呀,體會(huì)一下多進(jìn)程的效果吧。

另一方面運(yùn)行起來的程序是完全一次性加載到內(nèi)存當(dāng)中的,所以這些全局變量不會(huì)自動(dòng)銷毀,我們的程序畢竟是在一直運(yùn)行的。因此,如果稍加不注意,就會(huì)出現(xiàn)內(nèi)存泄露的問題。

綜上所述,global 聲明的變量、static 聲明的靜態(tài)變量、靜態(tài)函數(shù)、PHP 原生的超全局變量都有非常大的風(fēng)險(xiǎn),Swoole 直接干掉了默認(rèn)的超全局變量,而我們?nèi)绻褂萌肿兞康脑捯灿衅渌奶幚矸绞健_@個(gè)我們以后再說。

TCP

對(duì)于 Http 服務(wù)我們又進(jìn)行了一次復(fù)習(xí),并且通過這個(gè) Http 服務(wù)我們還看到了多進(jìn)程程序的特點(diǎn)以及在開發(fā)時(shí)需要轉(zhuǎn)變的一個(gè)重大的思維。當(dāng)然,這些東西我們?cè)诤竺鏁?huì)經(jīng)常接觸到。接下來,大家一起繼續(xù)學(xué)習(xí)了解一下使用 Swoole 來搭建一個(gè) TCP 服務(wù)端。

只要是學(xué)習(xí)過一點(diǎn)網(wǎng)絡(luò)相關(guān)知識(shí)的同學(xué)肯定都知道,我們的 Http 服務(wù)本身就是建立在 TCP 的基礎(chǔ)之上的。因此,其實(shí)要建立 TCP 服務(wù)的基本步驟和 Http 服務(wù)是沒啥差別的。最主要的就是監(jiān)聽的內(nèi)容不同。

//創(chuàng)建Server對(duì)象,監(jiān)聽 9501 端口
$server = new Swoole\Server('0.0.0.0'9501);

//監(jiān)聽連接進(jìn)入事件
$server->on('Connect'function ($server, $fd) {
    echo "Client: Connect.\n";
});

//監(jiān)聽數(shù)據(jù)接收事件
$server->on('Receive'function ($server, $fd, $reactor_id, $data) {
    $server->send($fd, "Server: {$data}");
});

//監(jiān)聽連接關(guān)閉事件
$server->on('Close'function ($server, $fd) {
    echo "Client: Close.\n";
});

//啟動(dòng)服務(wù)器
$server->start();

相比原生的 PHP 的 socket 函數(shù)來說,Swoole 是不是清晰方便很多。我們啟動(dòng)服務(wù)之后,使用 telnet 命令行就可以對(duì)這個(gè) TCP 服務(wù)器進(jìn)行測(cè)試了。

?  ~ telnet 192.168.56.133 9501
Trying 192.168.56.133...
Connected to 192.168.56.133.
Escape character is '^]'.
Hello
Server: Hello
App
Server: App
^]
telnet> quit
Connection closed.

Swoole 中還有對(duì)應(yīng)的 TCP 和 UDP 客戶端,這個(gè)我們后面再說。

UDP

UDP 和 TCP 的區(qū)別相信不用我多說了吧,這玩意不建立可靠連接的,但是速度快,所以現(xiàn)在的各種視頻直播之類的應(yīng)用全是建立在 UDP 之上的??梢哉f是支撐當(dāng)前短視頻和直播時(shí)代的基石了。

$server = new Swoole\Server('0.0.0.0'9501, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);

//監(jiān)聽數(shù)據(jù)接收事件
$server->on('Packet'function ($server, $data, $clientInfo) {
    var_dump($clientInfo);
    $server->sendto($clientInfo['address'], $clientInfo['port'], "Server:{$data}");
});

//啟動(dòng)服務(wù)器
$server->start();

寫法也基本都是類似的,不同的還是監(jiān)聽的內(nèi)容不同。由于它不建立連接,所以我們只需要監(jiān)聽接收到的數(shù)據(jù)包信息就可以了。

?  ~ nc -vuz 192.168.56.133 9501
Connection to 192.168.56.133 port 9501 [udp/\*] succeeded!

?  ~ nc -vu 192.168.56.133 9501
Connection to 192.168.56.133 port 9501 [udp/*] succeeded!
Server:XServer:XServer:XServer:Xall
Server:all
^C

對(duì)于命令行的測(cè)試來說,我們也不能使用 telnet 了,在這里,我使用的也是 Linux 環(huán)境中比較常見的 nc 命令來進(jìn)行測(cè)試的。

總結(jié)

今天我們就是簡(jiǎn)單地先看一下在整個(gè) Swoole 中,Http、TCP、UDP 服務(wù)是如何跑起來的,另外也嘗試了一下多進(jìn)程對(duì)于全局變量的影響。其實(shí)要學(xué)習(xí) Swoole ,就不可避免地要學(xué)習(xí)到很多計(jì)算機(jī)相關(guān)的基礎(chǔ)知識(shí),如果你還沒有這方面的準(zhǔn)備的話,可以先看看操作系統(tǒng)、計(jì)算機(jī)組成原理相關(guān)的內(nèi)容。畢竟我也不會(huì)講得太詳細(xì),也達(dá)不到來講這些基礎(chǔ)理論知識(shí)的水平。所以,有相關(guān)的內(nèi)容我也只能盡已所能地去稍帶地提出,畢竟我自己也還是在不斷學(xué)習(xí)這些基礎(chǔ)的過程之中的。

測(cè)試代碼:

https://github.com/zhangyue0503/swoole/blob/main/2.基礎(chǔ)/source/2.2Http、TCP、UDP服務(wù).php

參考文檔:

https://wiki.swoole.com/#/start/start_tcp_server

https://wiki.swoole.com/#/start/start_udp_server

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Swoole
Swoole 2.0 正式版發(fā)布,協(xié)程特性支持 PHP 7
php搭建swooleTCP服務(wù)器
PHP開發(fā)者的福音,解讀PHP異步通信框架Swoole的機(jī)制
PHP構(gòu)建這個(gè)框架后,開發(fā)、運(yùn)維、性能得到了全面的提升
常見協(xié)議、端口
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服