亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

swoole 服務(wù)端120行代碼構(gòu)建一個(gè)websocket 聊天室.

韓冰 / 609人閱讀

摘要:的異步并行高性能網(wǎng)絡(luò)通信引擎,使用純語(yǔ)言編寫,提供了語(yǔ)言的異步多線程服務(wù)器,異步網(wǎng)絡(luò)客戶端,異步,異步,數(shù)據(jù)庫(kù)連接池,,消息隊(duì)列,毫秒定時(shí)器,異步文件讀寫,異步查詢。內(nèi)置了服務(wù)器端客戶端服務(wù)器端。

swoole :http://www.swoole.com/
PHP的異步、并行、高性能網(wǎng)絡(luò)通信引擎,使用純C語(yǔ)言編寫,提供了PHP語(yǔ)言的異步多線程服務(wù)器,異步TCP/UDP網(wǎng)絡(luò)客戶端,異步MySQL,異步Redis,數(shù)據(jù)庫(kù)連接池,AsyncTask,消息隊(duì)列,毫秒定時(shí)器,異步文件讀寫,異步DNS查詢。 Swoole內(nèi)置了Http/WebSocket服務(wù)器端/客戶端、Http2.0服務(wù)器端。

7-22更新------ 昨天已經(jīng)用面向?qū)ο蠛蛂edis重做了一次,現(xiàn)在支持切換分組,私信了.并且對(duì)其他地方也做了一些優(yōu)化. 視頻演示: http://www.bilibili.com/video... 視頻中的列表沒有正常刷新漏洞已修復(fù) github : https://github.com/buffge/buf...

demo 地址 http://www.buffge.xin/buffcha... end------ 7-27更新

今天服務(wù)器被人攻擊了 他攻擊也許就是為了測(cè)試或者玩我,而且他也沒有得逞
他利用我的redis的漏洞來攻擊我,因?yàn)槲冶镜赜靡粋€(gè)可視化軟件去查看我服務(wù)器的數(shù)據(jù)庫(kù),所以我
開放的權(quán)限并且沒有加密,之后有人想透過redis 給我服務(wù)器上傳腳本. 不過這個(gè)腳本就是重復(fù)運(yùn)行而已,應(yīng)該是個(gè)
練手的.他這個(gè)腳本沒有運(yùn)行起來,因?yàn)槲襯edis 的權(quán)限很低. 他首先給我redis里面加入了這樣一句話

然后想讓這個(gè)腳本在我服務(wù)器中循環(huán)運(yùn)行.真的可惡.我好心開源給大家看了玩玩,我也沒空去搞那么安全那么好 但是就是有這種人渣來黑我.
等過幾天我忙完了手上的事重新開啟這個(gè)聊天室并添加新功能 和新樣式 不說了,我先舉報(bào)去了,我已經(jīng)找到他的ip和他的群了.就看tx管不管了.bye~
-------end


昨晚一直在學(xué)習(xí)swoole. 終于搞出了一個(gè)多人聊天室.新手可以看看,高玩請(qǐng)直接右上角.

思路:

 1:用戶登錄主頁(yè)面,此時(shí)后臺(tái)將用戶放入數(shù)據(jù)庫(kù)(我不會(huì)redis memcached 等),
 數(shù)據(jù)庫(kù)格式為

第一次登錄只需要將fd插入就行了.

2:此時(shí)如果不進(jìn)行注冊(cè),那么就無(wú)法發(fā)送信息給全局.
如果注冊(cè)了 那么填寫用戶名,ajax請(qǐng)求 將用戶名進(jìn)行加鹽信息摘要獲得token.
注冊(cè)成功后發(fā)送token:117fdba5e4d4050ed18ffd85ac86ed5b5d72dec6a271f4e4f6a6e03f4b957cd4:user_name:張三123
這樣的一個(gè)字符串給服務(wù)器,服務(wù)器會(huì)進(jìn)行token 和名稱驗(yàn)證,如果是正確的token.那么將用戶信息插入到數(shù)據(jù)庫(kù).
并通知其他websocket 有新用戶上線.

3:快樂的聊天吧.

路上遇到的坑:

        1:我原本準(zhǔn)備在server.php(就是swoole 后臺(tái)服務(wù))創(chuàng)建一個(gè)對(duì)象,
        存儲(chǔ)所有訪客的信息 姓名等等,但是他不共享這個(gè)對(duì)象,我覺得可以用redis 緩存起來,
        我這里就寫了玩的,就用mysql弄了,也沒有面向?qū)ο?
        2:不能用session  反正用了 之后就是各種問題,我原本是準(zhǔn)備用session 存儲(chǔ)用戶名稱的.
        后臺(tái)沒辦法想出一個(gè)加密token 然后存入數(shù)據(jù)庫(kù),
        具體的token是這樣的.
        


注冊(cè)時(shí)候用鹽和sha256生成token,然后去swoole 服務(wù)器那邊驗(yàn)證的時(shí)候也用同樣的用戶名和鹽進(jìn)行計(jì)算,看是否一樣.如果一樣 說明是正確的登錄了. 我不知道這個(gè)方法好不好.以前只會(huì)session,這個(gè)是昨晚突然想到的.

服務(wù)器那邊的日志如下:

4個(gè)用戶的聊天界面如下:

服務(wù)器端 代碼 看注釋.寫的渣別說,我是菜鳥.

   
  <#時(shí)間 = "00:46:16">
  <#人物 = "buff" >
  <#備注 = " ">
 */
if (php_sapi_name() !== "cli") {
    exit("使用cli模式");
}
$serv = new SwooleWebsocketServer("192.168.1.109", 9501);
//回調(diào)函數(shù) 新建一個(gè)websocket連接時(shí) 觸發(fā)的事件
$serv->on("Open", function($server, $req) {
    $mysqli = new mysqli("127.0.0.1", "buffge", "daimin", "buffchat");
    $charsetsql = "set names utf8";
    $mysqli->query($charsetsql);
    //將新登陸的用戶 保存到mysql
    $sql = "INSERT INTO `users` (`fd`) VALUES ("{$req->fd}")";
    $mysqli->query($sql);
    if ($mysqli->affected_rows !== 1) {
        echo "插入數(shù)據(jù)失敗!sql== {$sql}";
    }
    echo "新客戶端連接: " . $req->fd . "時(shí)間:" . date("Y-n-j H:i:s") . "
";
    $userlist = "";
    //檢查當(dāng)前共有多少用戶在線
    $sql = "select `user_name` from users where `user_name`!=""";
    $res = $mysqli->query($sql);
    for ($i = 0; $i < $res->num_rows; $i++) {
        $result = $res->fetch_assoc();
        $userlist .= (""" . $result["user_name"] . "",");
    }
    $userlist = substr($userlist, 0, strlen($userlist) - 1);
    //通知用戶 當(dāng)前在線用戶列表
    $server->push($req->fd, "{"code":"4","users":[{$userlist}]}");
    $res->free();
    $mysqli->close();
});
//當(dāng)收到用戶的消息時(shí) 觸發(fā)事件
$serv->on("Message", function($server, $frame) {
    $mysqli = new mysqli("127.0.0.1", "buffge", "daimin", "buffchat");
    $charsetsql = "set names utf8";
    $mysqli->query($charsetsql);
    $sql = "select * from users where fd={$frame->fd}";
    $res = $mysqli->query($sql);
    $result = $res->fetch_assoc();
    //獲取當(dāng)前發(fā)消息的人的名稱
    $user_name = $result["user_name"];
    echo "收到來自客戶端{(lán)$frame->fd}的消息: " . $frame->data . "
";
    //當(dāng)用戶是第一個(gè)注冊(cè)時(shí)候(發(fā)送的語(yǔ)句前面5個(gè)字是token)
    if (strpos($frame->data, "token") === 0) {
        //如果數(shù)據(jù)庫(kù)中沒有令牌
        if ($result["token"] === null) {
            $userData = explode(":", $frame->data);
            $hash = hash("sha256", "daimin" . $userData[3]);
            if ($userData[1] == $hash) {
                $sql = "UPDATE `users` SET `token` = "{$hash}",`user_name` = "{$userData[3]}" WHERE `fd` = {$frame->fd}";
                $mysqli->query($sql);
                if ($mysqli->affected_rows !== 1) {
                    echo "更新用戶信息失敗, sql === {$sql}";
                    $server->push($frame->fd, "{"code":"5","mes":"更新用戶信息失敗"}");
                }
                $server->push($frame->fd, "{"code":"3","user_name":"{$userData[3]}"}");
                $res->free();
                $userlist = "";
                //檢查當(dāng)前共有多少用戶在線
                $sql = "select `user_name` from users where `user_name`!=""";
                $res = $mysqli->query($sql);
                for ($i = 0; $i < $res->num_rows; $i++) {
                    $result = $res->fetch_assoc();
                    $userlist .= (""" . $result["user_name"] . "",");
                }
                $userlist = substr($userlist, 0, strlen($userlist) - 1);
                //通知所有用戶 當(dāng)前在線用戶列表
                foreach ($server->connections as $fd) {
                    $server->push($fd, "{"code":"4","users":[{$userlist}]}");
                }
                echo "新注冊(cè)用戶 {$userData[3]}
";
            }
            else {
                $server->push($frame->fd, "{"code":"5","mes":"token錯(cuò)誤"}");
            }
        }
        //如果只是發(fā)送包含token這個(gè)字符串的語(yǔ)句 群發(fā)
        else {
            foreach ($server->connections as $fd) {
                $server->push($fd, "{"code":"2","mes":"{$frame->data}","user_name":"{$user_name}"}");
            }
        }
    }
    //如果不是注冊(cè)用戶
    else {
        //如果沒有令牌
        if ($result["token"] === null) {
            $server->push($frame->fd, "{"mes":"請(qǐng)先登錄!"}");
            return;
        }
        //將換行轉(zhuǎn)換為br
        $mes = nl2br($frame->data);
        //格式化json
        $mes = str_replace("
", "", $mes);
        //群發(fā)消息
        foreach ($server->connections as $fd) {
            $server->push($fd, "{"code":"2","mes":"{$mes}","user_name":"{$user_name}"}");
        }
    }
    $res->free();
    $mysqli->close();
});
//當(dāng)websocket 斷開連接時(shí) 觸發(fā)事件
$serv->on("Close", function($server, $fd) {
    $mysqli = new mysqli("127.0.0.1", "buffge", "daimin", "buffchat");
    $charsetsql = "set names utf8";
    $mysqli->query($charsetsql);
    $sql = "DELETE FROM `users` WHERE `users`.`fd` = {$fd}";
    //當(dāng)用戶退出時(shí) 刪除信息
    $mysqli->query($sql);
    if ($mysqli->affected_rows !== 1) {
        echo "刪除用戶信息失敗, sql === {$sql}";
    }
    echo "客戶端{(lán)$fd}已斷開連接
";
    $mysqli->close();
});

$serv->start();

前端js 核心

websocket.onmessage = function (evt) {
    console.log(evt.data);
    var data = JSON.parse(evt.data);
    //根據(jù)code 判斷業(yè)務(wù)
    switch (data.code) {
        //個(gè)人消息
        case "1":
            break;
            //全局消息
        case "2":
            var $time = bf_get_time();//這是我自己寫的一個(gè)獲取時(shí)間函數(shù)
            var $mes = data.mes;//消息內(nèi)容
            var $user_name = data.user_name;//發(fā)消息的人
            var $who = $user_name === selfName ? "self" : "other";//根據(jù)名稱設(shè)置格式
            var $append = "

" + $user_name + "

" + $mes + "

" $(".gui_content").append($append); var $cont_scrTop = $(".gui_content").scrollTop(); var $list_height = $(".mes_item:last-of-type").height(); $(".gui_content").animate({"scrollTop": $cont_scrTop + $list_height}, 100); break; //通知注冊(cè)用戶成功消息 case "3": var $append = "
  • "; $append += data.user_name; $append += "
  • "; $(".user_list ul").append($append); $(".gui_user").html("

    歡迎 " + data.user_name + "

    "); selfName = data.user_name; break; //更新當(dāng)前在線列表 刪除的我沒寫~ case "4": var $append = ""; var $nowUser = $(".user_list ul li"); outer: for (var user in data.users) { for (var i = 0; i < $nowUser.length; i++) { if ($nowUser[i].innerText === data.users[user]) { continue outer; } } console.log(data.users[user]); $append += "
  • "; $append += data.users[user]; $append += "
  • "; } $(".user_list ul").append($append); break; case "5": alert(data.mes); break; } console.log("收到來自服務(wù)器的消息: " + data.code); };

    等有空了用面向?qū)ο髮懸淮伟裮ysql 換成redis,現(xiàn)在的代碼有點(diǎn)亂,一些功能也沒有寫,因?yàn)樘Я?連續(xù)寫了8小時(shí).

    如果有大神看的話 能不能告訴我 哪里該改進(jìn). 比如怎么驗(yàn)證用戶,用哪種方法存儲(chǔ)之類的.謝謝了

    文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/23284.html

    相關(guān)文章

    • Websocket解析及實(shí)現(xiàn)

      摘要:早期的輪詢是通過不斷自動(dòng)刷新頁(yè)面而實(shí)現(xiàn)的。長(zhǎng)輪詢的另一個(gè)問題是缺乏標(biāo)準(zhǔn)實(shí)現(xiàn)。服務(wù)器端接到這個(gè)請(qǐng)求后作出回應(yīng)并不斷更新連接狀態(tài)以保證客戶端和服務(wù)器端的連接不過期。協(xié)議解析協(xié)議包含兩部分一部分是握手,一部分是數(shù)據(jù)傳輸。 Websocket是什么? Websocket是一個(gè)因?yàn)閼?yīng)用場(chǎng)景越來越復(fù)雜而提出的,針對(duì)瀏覽器和web服務(wù)器之間雙向持續(xù)通信而設(shè)計(jì),而且優(yōu)雅地兼容HTTP的協(xié)議(我猜想:同...

      XboxYan 評(píng)論0 收藏0
    • 實(shí)戰(zhàn) swoole天室

      摘要:是一個(gè)請(qǐng)求對(duì)象,包含了客戶端發(fā)來的握手請(qǐng)求信息事件函數(shù)中可以調(diào)用向客戶端發(fā)送數(shù)據(jù)或者調(diào)用關(guān)閉連接事件回調(diào)是可選的當(dāng)服務(wù)器收到來自客戶端的數(shù)據(jù)幀時(shí)會(huì)回調(diào)此函數(shù)。 前言:了解概念之后就應(yīng)該練練手啦,不然就是巨嬰 有收獲的話請(qǐng)加顆小星星,沒有收獲的話可以 反對(duì) 沒有幫助 舉報(bào)三連 代碼倉(cāng)庫(kù) 實(shí)戰(zhàn)swoole【聊天室】 在線體驗(yàn) 準(zhǔn)備工作 需要先看初識(shí)swoole【上】,了解基本的服務(wù)端...

      andycall 評(píng)論0 收藏0
    • php只能做網(wǎng)站?基于swoole+websocket開發(fā)雙向通信應(yīng)用

      摘要:那么,是否就無(wú)法用來開發(fā)雙向通信的應(yīng)用呢答案是否定的。內(nèi)置通信支持,可以與程序基于進(jìn)行雙向通信。通信協(xié)議于年被定為標(biāo)準(zhǔn),并由補(bǔ)充規(guī)范。前言 眾所周知,PHP用于開發(fā)基于HTTP協(xié)議的網(wǎng)站應(yīng)用非常便捷。而HTTP協(xié)議是一種單向的通信協(xié)議,只能接收客戶端的請(qǐng)求,然后響應(yīng)請(qǐng)求,不能主動(dòng)向客戶端推送信息。因此,一些實(shí)時(shí)性要求比較高的應(yīng)用,如實(shí)時(shí)聊天、直播應(yīng)用、在線網(wǎng)頁(yè)游戲等,就不適合采用HTTP協(xié)議...

      番茄西紅柿 評(píng)論0 收藏0
    • php只能做網(wǎng)站?基于swoole+websocket開發(fā)雙向通信應(yīng)用

      摘要:那么,是否就無(wú)法用來開發(fā)雙向通信的應(yīng)用呢答案是否定的。內(nèi)置通信支持,可以與程序基于進(jìn)行雙向通信。通信協(xié)議于年被定為標(biāo)準(zhǔn),并由補(bǔ)充規(guī)范。前言 眾所周知,PHP用于開發(fā)基于HTTP協(xié)議的網(wǎng)站應(yīng)用非常便捷。而HTTP協(xié)議是一種單向的通信協(xié)議,只能接收客戶端的請(qǐng)求,然后響應(yīng)請(qǐng)求,不能主動(dòng)向客戶端推送信息。因此,一些實(shí)時(shí)性要求比較高的應(yīng)用,如實(shí)時(shí)聊天、直播應(yīng)用、在線網(wǎng)頁(yè)游戲等,就不適合采用HTTP協(xié)議...

      琛h。 評(píng)論0 收藏0
    • swoole 超簡(jiǎn)單 構(gòu)建天室.資辭 群聊,組聊,單聊.

      摘要:今天來做一個(gè)簡(jiǎn)單的聊天室支持換房間支持私信的寫的代碼有點(diǎn)渣里面有很多不是很好的地方畢竟我只是一個(gè)野生程序猿環(huán)境地址樣子差不多是這個(gè)樣子的我不想把代碼發(fā)到我的服務(wù)器上因?yàn)檫@個(gè)項(xiàng)目太小了很垃圾而且怕被攻擊這里有錄的一個(gè)演示視頻沒有廣告的你們可以 今天來做一個(gè)簡(jiǎn)單的聊天室,支持換房間,支持私信的. 寫的代碼有點(diǎn)渣,里面有很多不是很好的地方.畢竟我只是一個(gè)野生程序猿. 環(huán)境: php7.0...

      Towers 評(píng)論0 收藏0

    發(fā)表評(píng)論

    0條評(píng)論

    最新活動(dòng)
    閱讀需要支付1元查看
    <