基于swoole的websocket聊天室

一瓷炮、什么是websocket泪漂?
websocket協(xié)議是基于TCP協(xié)議的一種新的持久化網(wǎng)絡(luò)通信協(xié)議咧七。通過(guò)一次瀏覽器請(qǐng)求衰齐、服務(wù)器響應(yīng)(一次握手)搭建出一條網(wǎng)絡(luò)雙通道,實(shí)現(xiàn)服務(wù)器主動(dòng)推送信息給瀏覽器继阻。

websocket和http的關(guān)系

二耻涛、swoole的安裝
http://www.swoole.com
我直接在服務(wù)器上安裝的废酷。。抹缕。
三澈蟆、server.php(聊天室服務(wù)端)

<?php
//結(jié)合redis使用
$redis = new redis();
$result = $redis->connect("127.0.0.1", 6379);
$server = new swoole_websocket_server("0.0.0.0", "端口號(hào)");
$server->on('open', function (swoole_websocket_server $server, $request) {
    global $redis;
    $nfd = $request->fd;
    echo "客戶端{(lán)$nfd}成功接入\n";
    $redis->hset("User",$nfd,$nfd);//將客戶端id存入redis
    $users = $redis->hvals("User");
});
$server->on('message', function (swoole_websocket_server $server, $frame) {
    global $redis;
    $data = $frame->data;//客戶端發(fā)送的信息
    $fd = $frame->fd;//消息發(fā)送id
    //類型判斷
    $str = substr($data,0,8);
    if($str == '{"name":'){
        //登錄
        $data = json_decode($data);
        echo $fd.$data->name."登錄"."<br>";
        $redis->hset("name",$fd,$data->name);//保存客戶端昵稱
        $redis->hset("email",$fd,$data->email);//保存客戶端郵箱
        $users = $redis->hvals("User");//取回所有用戶
        foreach ($users as $u)
        {
            //對(duì)所有用戶發(fā)送消息
            $server->push($u ,'0@1@4@3'.$redis->hGet('name',$fd));
        }
    }else{
        //發(fā)送消息
        echo $fd."發(fā)送消息:".$data;
        $users = $redis->hvals("User");//取回所有用戶
        foreach ($users as $u)
        {
            //對(duì)所有用戶發(fā)送消息
            $server->push($u ,$redis->hGet('name',$fd).'說(shuō):'.$data);
        }
    }
});
$server->on('close', function ($ser, $fd) {
    global $redis;
    //清除用戶信息緩存
    $redis->hdel("User",$fd);
    $redis->hdel("name",$fd);
    $redis->hdel("email",$fd);
    $users = $redis->hvals("User");
    var_dump($users);
    echo "client {$fd} closed\n";
    //$redis->flushAll();
});
$server->start();
?>

四、client.php(聊天室客戶端)

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="UTF-8">
    <style>
        #top{
            width: 60%;
            height: 50px;
            text-align: left;
            margin: 0 auto;
            margin-top: 50px;
            background-color: #3c3c3c;
        }
        #room{
            width: 60%;
            height: 500px;
            text-align: center;
            margin: 0 auto;
            border: 1px solid ;
        }
        #left{
            width: 25%;
            float: left;
            text-align: center;
            margin: 30px;
            border: 1px solid #ccc;
            background-color: #E8E8D0;
        }
        #right{
            width: 60%;
            height: 90%;
            float: right;
            text-align: left;
            margin: 30px 30px 20px 20px;
            background-color: #F0F0F0;
        }
        #chat{
            width: 100%;
            height: 90%;
            margin-left: 10px;
        }
        #submit1{
            width: 100%;
            height: 50px;
            padding-bottom: 10px;
            margin-top: 15px;
        }
        #submit2{
            width: 100%;
            height: 50px;
            padding-bottom: 10px;
            margin-top: 15px;
        }
    </style>
    <script type="text/javascript">
        if(window.WebSocket){
            var webSocket = new WebSocket("ws://服務(wù)端ip:端口號(hào)");
            webSocket.onopen = function (event) {
                //webSocket.send("Hello,WebSocket!");
            };
            webSocket.onmessage = function (event) {
                var content = document.getElementById('chat');
                var left = document.getElementById('left');
                if(event.data instanceof Blob) {
                    var img = document.createElement("img");
                    img.src = window.URL.createObjectURL(event.data);
                    content.appendChild(img);
                }else {
                    var str = event.data.substring(0,7);
                    if(str == '0@1@4@3'){
                        //登錄
                        var name = event.data.substring(7,event.data.length);
                        left.innerHTML = left.innerHTML.concat('<p style="margin-left:0px;height:20px;line-height:20px;">'+name+'</p>');
                    }else{
                        //發(fā)送消息
                        content.innerHTML = content.innerHTML.concat('<p style="margin-left:20px;height:20px;line-height:20px;">'+event.data+'</p>');
                    }
                }
            };

            //登錄
            var login = function () {
                var name = document.getElementById('name').value;
                var email = document.getElementById('email').value;
                if(name == ''){
                    alert('請(qǐng)輸入昵稱');
                }else if(email == ''){
                    alert('請(qǐng)輸入郵箱');
                }else{
                    var arr = new Array();
                    arr['name'] = name;
                    arr['email'] = email;
                    var a = '{"name":"'+name+'","email":"'+email+'"}';
                    webSocket.send(a);
                    document.getElementById('submit1').style.display = 'none';
                    document.getElementById('submit2').style.display = '';
                }
            }
            //發(fā)送信息
            var sendMessage = function(){
                var data = document.getElementById('message').value;
                if(data == ''){
                    alert('消息不能為空');
                }else{
                    webSocket.send(data);
                    document.getElementById('message').value = '';
                }
            }
        }else{
            console.log("您的瀏覽器不支持WebSocket");
        }
    </script>
</head>
<body>
<div id="top">
    <p style="line-height: 50px;margin-left: 20px;color: white">聊天室測(cè)試——swoole</p>
</div>
<div id="room">
    <div id="left">
        <span style="color: red;border-bottom:1px dashed red;overflow-y:auto;">在線用戶</span>
    </div>
    <?php
    if(app\helpers\Isphone::is_mobile_request()) {
        ?>
        <div id="right" style="height: 70%;width: 50%">
            <div id="chat" style="overflow-y:auto;">
                <p style="text-align: center">歡迎進(jìn)入聊天室卓研!</p>
            </div>
            <div id="submit1">
                    
                <input type="text" id="name" name="name" placeholder="昵稱" style="width: 120px"/>
                <input type="text" id="email" name="email" placeholder="郵箱" style="width: 120px"/>
                <button onclick="login()">登錄</button>
            </div>
            <div id="submit2" style="display: none;">
                    
                <input type="text" id="message" style="width: 70%">
                <button onclick="sendMessage()" style="height:25px;width:75px;">發(fā)送</button>
            </div>
        </div>
        <?php
    }else {
        ?>
        <div id="right">
            <div id="chat" style="overflow-y:auto;">
                <p style="text-align: center">歡迎進(jìn)入聊天室趴俘!</p>
            </div>
            <div id="submit1">
                    
                <input type="text" id="name" name="name" placeholder="昵稱"/>
                <input type="text" id="email" name="email" placeholder="郵箱"/>
                <button onclick="login()">登錄</button>
            </div>
            <div id="submit2" style="display: none;">
                    
                <input type="text" id="message" style="width: 70%">
                <button onclick="sendMessage()" style="height:25px;width:75px;">發(fā)送</button>
            </div>
        </div>
        <?php
    }
    ?>
</div>
</body>
</html>

五、學(xué)習(xí)總結(jié)
初次接觸到網(wǎng)絡(luò)協(xié)議發(fā)現(xiàn)這里還需要自己更深入全面的學(xué)習(xí)和了解奏赘。
在消息推送上websocket相比較于http更方便快捷寥闪,避免了瀏覽器無(wú)時(shí)無(wú)刻的請(qǐng)求服務(wù)器,由被動(dòng)變主動(dòng)磨淌。
linux命令:
nohup command &
用途:命令不掛斷疲憋、后臺(tái)運(yùn)行。
中止nohup命令:ps -ef | grep command
kill -9 pid
聊天室弊端:
1.頁(yè)面過(guò)于簡(jiǎn)陋伦糯、用戶下線沒(méi)有提示柜某。
2.服務(wù)端沒(méi)有涉及到數(shù)據(jù)庫(kù)操作嗽元,無(wú)法查看歷史聊天記錄敛纲。

github:https://github.com/aishangkaoniangao/websocket-chat

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市剂癌,隨后出現(xiàn)的幾起案子淤翔,更是在濱河造成了極大的恐慌,老刑警劉巖佩谷,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旁壮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡谐檀,警方通過(guò)查閱死者的電腦和手機(jī)抡谐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)桐猬,“玉大人麦撵,你說(shuō)我怎么就攤上這事±7荆” “怎么了免胃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)惫撰。 經(jīng)常有香客問(wèn)我羔沙,道長(zhǎng),這世上最難降的妖魔是什么厨钻? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任扼雏,我火速辦了婚禮坚嗜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诗充。我一直安慰自己惶傻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布其障。 她就那樣靜靜地躺著银室,像睡著了一般。 火紅的嫁衣襯著肌膚如雪励翼。 梳的紋絲不亂的頭發(fā)上蜈敢,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音汽抚,去河邊找鬼抓狭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛造烁,可吹牛的內(nèi)容都是我干的否过。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惭蟋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼苗桂!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起告组,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤煤伟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后木缝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體便锨,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年我碟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了放案。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡矫俺,死狀恐怖吱殉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恳守,我是刑警寧澤考婴,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站催烘,受9級(jí)特大地震影響沥阱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伊群,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一考杉、第九天 我趴在偏房一處隱蔽的房頂上張望策精。 院中可真熱鬧,春花似錦崇棠、人聲如沸咽袜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)询刹。三九已至,卻和暖如春萎坷,著一層夾襖步出監(jiān)牢的瞬間凹联,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工哆档, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔽挠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓瓜浸,卻偏偏與公主長(zhǎng)得像澳淑,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子插佛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容