[Swoole] 在Ubuntu下安裝、快速開始

本文主要講述在 Ubuntu 下編譯安裝 Swoole,並根據官方文檔給出的demo進行了測試和搬運,包括:TCP服務器、UDP服務器、HTTP服務器、WebSocket服務器、異步客戶端、定時器和協程相關,通過模仿官方例子領略Swoole給PHPer帶來全新的編程模式和思想。



運行環境:win10 下的 UbuntuPHP7.2Swoole4.3

參考文檔: https://wiki.swoole.com/wiki/page/p-quickstart.html


  • 下載解壓
sudo wget https://github.com/swoole/swoole-src/archive/v4.3.6.tar.gz
cp v4.3.6.tar.gz swoole-v4.3.6.tar.gz
tar -zxvf swoole-v4.3.6.tar.gz
cd swoole-v4.3.6
  • 安裝依賴
# 根據下面的編譯提示進行選擇安裝

sudo apt-get install php-dev
sudo apt-get install autoconf
  • 編譯安裝
# 根據自己 php 安裝的目錄
cd swoole-v4.3.6
sudo make install

make 的結果:

Libraries have been installed in:

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.

Build complete.
Don't forget to run 'make test'.

sudo make install 的結果:

Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20170718/
Installing header files:          /usr/local/php/include/php/
  • 配置 php.ini
# 編譯安裝成功後,在 php.ini 文件加入

# extension=/usr/lib/php/20170718/swoole.so

查看是否加載 swoole 擴展

php -m
  • 錯誤排查(可忽略)

下面錯誤很明顯,需要指定 php-conf 路徑:

configure: error: Cannot find php-config. Please use --with-php-config=PATH


./configure --with-php-config=/usr/local/php/bin/php-config


a) TCP 服務器

# 創建 php 文件
vi tcp_server.php
    $serv = new Swoole\Server("", 9501); 
    $serv->on('Connect', function ($serv, $fd) {  
        echo "Client: Connect.\n";
    $serv->on('Receive', function ($serv, $fd, $from_id, $data) {
        $serv->send($fd, "Server: ".$data);
    $serv->on('Close', function ($serv, $fd) {
        echo "Client: Close.\n";
# 程序運行測試

# 運行 server
php tcp_server.php

# 使用telnet 測試(退出telnet:Ctrl+] 回車,輸入quit 回車)
telnet 9501

b) UDP 服務器

vi udp_server.php
    $serv = new swoole_server("", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); 
    $serv->on('Packet', function ($serv, $data, $clientInfo) {
        $serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
# 運行
php udp_server.php

# 使用 netcat 連接
netcat -u 9502

c) HTTP 服務器

vi http_server.php
    $http = new Swoole\Http\Server("", 9501);
    $http->on('request', function ($request, $response) {
        if ($request->server['path_info'] == '/favicon.ico' ||    $request->server['request_uri'] == '/favicon.ico') {
            return $response->end();
        var_dump($request->get, $request->post);
        $response->header("Content-Type", "text/html; charset=utf-8");
        $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
# 程序運行測試

php http_server.php

# 瀏覽器訪問

d) WebSocket 服務器



vi ws_server.php
    $ws = new swoole_websocket_server("", 9502);
    $ws->on('open', function ($ws, $request) {
        var_dump($request->fd, $request->get, $request->server);
        $ws->push($request->fd, "hello, welcome\n");
    $ws->on('message', function ($ws, $frame) {
        echo "Message: {$frame->data}\n";
        $ws->push($frame->fd, "server: {$frame->data}");
    $ws->on('close', function ($ws, $fd) {
        echo "client-{$fd} is closed\n";
# 程序運行

php ws_server.php

var wsServer = 'ws://';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
    console.log("Connected to WebSocket server.");

websocket.onclose = function (evt) {

websocket.onmessage = function (evt) {
    console.log('Retrieved data from server: ' + evt.data);

websocket.onerror = function (evt, e) {
    console.log('Error occured: ' + evt.data);

e) 定時器


vi timer_tick.php
$timerId = swoole_timer_tick(2000, function ($timer_id) {
    echo "tick-2000ms\n";

swoole_timer_after(9000, function () use ($timerId) {
    echo "after-9000ms.\n";
php timer_tick.php

f) 同步、異步 TCP 客戶端

vi tcp_client.php
    $client = new swoole_client(SWOOLE_SOCK_TCP);
    if (!$client->connect('', 9501, 0.5))
        die("connect failed.");
    if (!$client->send("hello world"))
        die("send failed.");
    $data = $client->recv();
    if (!$data)
        die("recv failed.");
    echo $data;

# 異步只能用於cli
vi tcp_async_client.php
    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
    $client->on("connect", function($cli) {
        $cli->send("hello world\n");
    $client->on("receive", function($cli, $data){
        echo "Received: ".$data."\n";
    $client->on("error", function($cli){
        echo "Connect failed\n";
    $client->on("close", function($cli){
        echo "Connection close\n";
    $client->connect('', 9501, 0.5);

g) 協程客戶端

vi xxx.php
    $http = new swoole_http_server("", 9501);
    $http->on('request', function ($request, $response) {
        $db = new Swoole\Coroutine\MySQL();
            'host' => '',
            'port' => 3306,
            'user' => 'user',
            'password' => 'pass',
            'database' => 'test',
        $data = $db->query('select * from test_table');

h) 協程:併發 shell_exec

vi xxx.php
    $c = 10;
    while($c--) {
        go(function () {
            //這裏使用 sleep 5 來模擬一個很長的命令
            co::exec("sleep 5");

i) 協程:Go + Chan + Defer


還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.