1. 程式人生 > >swoole聊天室demo

swoole聊天室demo

實現效果

socket聊天室

github demo

SWOOLE是什麼

官網如是說:Swoole:面向生產環境的 PHP 非同步網路通訊引擎

使 PHP 開發人員可以編寫高效能的非同步併發 TCP、UDP、Unix Socket、HTTP,WebSocket 服務。Swoole 可以廣泛應用於網際網路、行動通訊、企業軟體、雲端計算、網路遊戲、物聯網(IOT)、車聯網、智慧家居等領域。 使用 PHP + Swoole 作為網路通訊框架,可以使企業 IT 研發團隊的效率大大提升,更加專注於開發創新產品。

安裝

//linux:
pecl install swoole
//mac
brew install swoole

以上平臺筆者都測試過,順利安裝,自己修改下ini extension

使用

<?php
$server = new swoole_websocket_server("127.0.0.1", 9502);

$server->on('open', function($server, $req) {
    echo "connection open: {$req->fd}\n";
});

$server->on('message', function($server, $frame) {
    echo "received message: {$frame->data}\n";
    $server->push($frame->fd, json_encode(["hello", "world"]));
});

$server->on('close', function($server, $fd) {
    echo "connection close: {$fd}\n";
});

$server->start();

是不是感覺so easy

實戰

要想實現能聊天自己還需要做點東西

//客戶端與伺服器連線時觸發
$server->on('open')

//客戶端向伺服器傳送訊息時觸發
$server->on('message')

//連線關閉時觸發
$server->on('close')

明白個自己的執行時間,我們就可以在對應的時間加上邏輯了,以下為例子(http://lts.yuuuu.wang)的原始碼:

#! /usr/local/bin/php
<?php
date_default_timezone_set('Asia/Shanghai');

$server = new swoole_websocket_server("192.168.13.201", 9502);

//connects方法主要是管理當前線上使用者的,主要是為了廣播時能將訊息退給各自客戶端,目前筆者是通過寫檔案,實際應用可以更換其他方式儲存
connects(0 , 'clear');

$server->on('open', function($server, $req){
    connects($req->fd);
});

$server->on('message', function($server, $frame){
    $msg = explode('~' , $frame->data);

    $rep = ['code' => $msg[0] , 'user' => $msg[1] , 'msg' => $msg[2] , 'time' => date('H:i:s')];

    $connects = connects(0,'read');

    foreach($connects as $v) {
        $server->push($v, json_encode($rep));
    }


});

$server->on('close', function($server, $fd){
    connects($fd , 'out');
});

$server->start();

/**
 * 對線上使用者進行管理
 * @param int $cid 客戶端連線對應在服務端的socket id
 * @param string $op 操作 上線 in 下線 out 讀取線上列表 read 清空線上列表 clear
 * @return array|bool|mixed|string|void
 */
function connects($cid = 0 , $op = 'in')
{
    $connects = file_get_contents('/tmp/t.php');
    $connects = @json_decode($connects , true);

    switch($op){
        case 'out':
            if(!$connects){
                return;
            }
            if(in_array($cid , $connects)){
                $connects = array_filter($connects , function($v) use ($cid){
                    if($v != $cid){
                        return true;
                    }
                });
                file_put_contents('/tmp/t.php' , json_encode($connects));
            }
            break;
        case 'read':
            if(!$connects){
                return;
            }
            return $connects;
            break;
        case 'clear':
            file_put_contents('/tmp/t.php' , json_encode([]));
            break;
        default:
            if(!$connects){
                $connects = [];
            }
            $n = array_merge($connects , array($cid));
            file_put_contents('/tmp/t.php' , json_encode($n));
            break;
    }
}