成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

一個(gè)簡(jiǎn)單混合協(xié)議通訊列子,物聯(lián)網(wǎng)和互聯(lián)網(wǎng)通訊。

王軍 / 1789人閱讀

摘要:初始化發(fā)送消息判斷用戶是否登錄如果沒(méi)有登錄拒絕連接斷開(kāi)清除信息處理協(xié)議主要是方法,輪訓(xùn)獲取消息。

這個(gè)列子主要討論Tcp,WebSockethttp之間的通訊。長(zhǎng)連接和長(zhǎng)連接通訊,長(zhǎng)連接和短連接通訊。其他協(xié)議同理可得

Tcp: 代表硬件設(shè)備
WebSocket: 代表客戶端 
http: 代表網(wǎng)頁(yè)  

本列子是基于one框架 (https://github.com/lizhichao/one) 開(kāi)發(fā).

配置協(xié)議 監(jiān)聽(tīng)端口

由于swoole的模型 WebSocket server 包含 http server , http server 包含 tcp server 。

所以我們配置主服務(wù)為 WebSocket server ,添加兩個(gè)http 和 tcp 監(jiān)聽(tīng)。配置文件如下:

return [
    "server" => [
        "server_type" => OneSwooleOneServer::SWOOLE_WEBSOCKET_SERVER,
        "port" => 8082,
        "action" => AppTestMixProWs::class,
        "mode" => SWOOLE_PROCESS,
        "sock_type" => SWOOLE_SOCK_TCP,
        "ip" => "0.0.0.0",
        "set" => [
            "worker_num" => 5
        ]
    ],
    "add_listener" => [
        // http 監(jiān)聽(tīng)
        [
            "port" => 8081,
            "action" => AppServerAppHttpPort::class, 
            "type" => SWOOLE_SOCK_TCP,
            "ip" => "0.0.0.0",
            "set" => [
                "open_http_protocol" => true,
                "open_websocket_protocol" => false
            ]
        ],
        // tcp 監(jiān)聽(tīng)
        [
            "port" => 8083,
            "pack_protocol" => OneProtocolText::class, // tcp 打包,解包協(xié)議,方便在終端調(diào)試 我們使用 text 協(xié)議. 換行符 表示一個(gè)包的結(jié)束
            "action" => AppTestMixProTcpPort::class,
            "type" => SWOOLE_SOCK_TCP,
            "ip" => "0.0.0.0",
            "set" => [
                "open_http_protocol" => false,
                "open_websocket_protocol" => false
            ]
        ]
    ]
];

接下來(lái)去 AppTestMixProWsAppTestMixProTcpPort 實(shí)現(xiàn)各種事件處理。
AppServerAppHttpPort 是框架內(nèi)置的,通過(guò)路由處理http請(qǐng)求的,配置路由即可。

配置路由
// 首頁(yè)
Router::get("/mix", [
    "use"    => HttpController::class . "@index",
    "middle" => [AppTestMixProTestMiddle::class . "@isLogin"] // 中間件 如果用戶登錄了 直接跳轉(zhuǎn)到相應(yīng)的頁(yè)面
]);

Router::group([
        "middle" => [AppTestMixProTestMiddle::class . "@checkSession"] // 中間件 讓用戶登錄后 才能進(jìn)入聊天頁(yè)面 http websocket 都能獲取到這個(gè) session
    ], function () {

    // websocket 頁(yè)面
    Router::get("/mix/ws", HttpController::class . "@ws");
    
    // http 頁(yè)面
    Router::get("/mix/http", HttpController::class . "@http");
    
    // http 輪訓(xùn)消息接口
    Router::post("/mix/http/loop", HttpController::class . "@httpLoop");
    
    // http 發(fā)送消息接口
    Router::post("/mix/http/send", HttpController::class . "@httpSend");

});

配置的都是 http 協(xié)議路由。 websocket和tpc我們直接在回調(diào)action處理。如果你的項(xiàng)目復(fù)雜也可以配置相應(yīng)的路由。one框架的路由支持任何協(xié)議,使用方法也是統(tǒng)一的。

處理tcp協(xié)議

其中__construct,onConnect,onClose 不是必須的。
如果你想在服務(wù)器運(yùn)行開(kāi)始時(shí)最一些事情就寫到 __construct里面。
onConnect 當(dāng)有客戶端連接時(shí)觸發(fā),每個(gè)客戶端觸發(fā)一次
onClose 當(dāng)有客戶端連接斷開(kāi)時(shí)觸發(fā),每個(gè)客戶端觸發(fā)一次

class TcpPort extends Tcp
{
    use Funs;

    private $users = [];

    /**
     * @var Ws
     */
    protected $server;

    /**
     * @var Client
     */
    protected $global_data;

    public function __construct($server, $conf)
    {
        parent::__construct($server, $conf);
        $this->global_data = $this->server->global_data;
    }

    // 終端連接上服務(wù)器時(shí)
    public function onConnect(swoole_server $server, $fd, $reactor_id)
    {
        $name             = uuid();
        $this->users[$fd] = $name;
        $this->sendTo("all", json_encode(["v" => 1, "n" => $name]));
        $this->sendToTcp($fd, json_encode(["v" => 4, "n" => $this->getAllName()]));
        $this->global_data->bindId($fd, $name);
        $this->send($fd, "你的名字是:" . $name);
    }

    // 消息處理 像某個(gè)name 發(fā)送消息
    public function onReceive(swoole_server $server, $fd, $reactor_id, $data)
    {
        $arr = explode(" ", $data);
        if (count($arr) !== 3 || $arr[0] !== "send") {
            $this->send($fd, "格式不正確");
            return false;
        }
        $n = $arr[1];
        $d = $arr[2];
        $this->sendTo($n, json_encode(["v" => 3, "n" => $d]));
    }

    // 下線 通知所有其他終端,解除與fd的關(guān)系綁定。
    public function onClose(swoole_server $server, $fd, $reactor_id)
    {
        echo "tcp close {$fd} 
";
        $this->global_data->unBindFd($fd);
        $this->sendTo("all", json_encode(["v" => 2, "n" => $this->users[$fd]]));
        unset($this->users[$fd]);
    }

}

定義了一個(gè)公共的traitFuns主要實(shí)現(xiàn)兩個(gè)方法,獲取所有的終端(tcp,ws,http),和向某個(gè)用戶發(fā)送消息 。在ws、http都會(huì)用到這個(gè)
在構(gòu)造函數(shù)我們初始化了一個(gè) global_data 用來(lái)保存,名稱和fd的關(guān)系。你也可以使用方式儲(chǔ)存。因?yàn)閒d沒(méi)次連接都不同。global_data是one框架內(nèi)置的。
終端連接上服務(wù)器時(shí)觸發(fā)事件 onConnect ,我們給這個(gè)終端取個(gè)名字,并把關(guān)系保存在 global_data。 通知所有終端有個(gè)新終端加入,并告訴剛加入的終端當(dāng)前有哪些終端在線。

處理 websocket 協(xié)議

其中__construct,onHandShake,onOpen,onClose 不是必須的。

onHandShake,onOpen 是配合使用的,如果onOpen返回false服務(wù)器會(huì)拒絕連接。
onOpen,onMessage,onClose可以拿到當(dāng)前用戶的session信息和http是相通的。

class Ws extends WsServer
{
    use Funs;

    private $users = [];

    /**
     * @var Client
     */
    public $global_data = null;

    public function __construct(swoole_server $server, array $conf)
    {
        parent::__construct($server, $conf);
        $this->global_data = new Client();
    }
    
    // 初始化session
    public function onHandShake(swoole_http_request $request, swoole_http_response $response)
    {
        return parent::onHandShake($request, $response);
    }

    // ws 發(fā)送消息
    public function onMessage(swoole_websocket_server $server, swoole_websocket_frame $frame)
    {
        $data = $frame->data;
        $arr  = json_decode($data, true);
        $n    = $arr["n"];
        $d    = $arr["d"];
        $this->sendTo($n, json_encode(["v" => 3, "n" => $d]));

    }

    // 判斷用戶是否登錄 如果沒(méi)有登錄拒絕連接
    public function onOpen(swoole_websocket_server $server, swoole_http_request $request)
    {
        $name = $this->session[$request->fd]->get("name");
        if ($name) {
            $this->users[$request->fd] = $name;
            $this->sendTo("all", json_encode(["v" => 1, "n" => $name]));
            $this->global_data->bindId($request->fd, $name);
            return true;
        } else {
            return false;
        }
    }

    // ws 斷開(kāi)清除信息
    public function onClose(swoole_server $server, $fd, $reactor_id)
    {
        echo "ws close {$fd} 
";
        $this->global_data->unBindFd($fd);
        $this->sendTo("all", json_encode(["v" => 2, "n" => $this->users[$fd]]));
        unset($this->users[$fd]);
    }
}
處理 http 協(xié)議

主要是 httpLoop 方法,輪訓(xùn)獲取消息。因?yàn)閔ttp是短連接,發(fā)給http的信息我們是先存放在$global_data,然后直接這里讀取。防止連接間隙丟信息。

class HttpController extends Controller
{

    use Funs;

    /**
     * @var Ws
     */
    protected $server;

    /**
     * @var Client
     */
    protected $global_data;


    public function __construct($request, $response, $server = null)
    {
        parent::__construct($request, $response, $server);
        $this->global_data = $this->server->global_data;
    }

    /**
     * 首頁(yè)
     */
    public function index()
    {
        $code = sha1(uuid());
        $this->session()->set("code", $code);
        return $this->display("index", ["code" => $code]);
    }

    /**
     * ws頁(yè)面
     */
    public function ws()
    {
        $name = $this->session()->get("name");
        if (!$name) {
            $name = uuid();
            $this->session()->set("name", $name);
        }
        return $this->display("ws",["users" => $this->getAllName(),"name" => $name]);
    }

    /**
     * http 頁(yè)面
     */
    public function http()
    {
        $name = $this->session()->get("name");
        if (!$name) {
            $name = uuid();
            $this->session()->set("name", $name);
        }
        $this->global_data->set("http.{$name}", 1, time() + 60);
        $this->sendTo("all", json_encode(["v" => 1, "n" => $name]));
        return $this->display("http", ["list" => $this->getAllName(), "name" => $name]);
    }

    /**
     * http輪訓(xùn)
     */
    public function httpLoop()
    {
        $name = $this->session()->get("name");
        $this->global_data->set("http.{$name}", 1, time() + 60);
        $i = 0;
        do {
            $data = $this->global_data->getAndDel("data.{$name}");
            $i++;
            co::sleep(0.1);
        } while ($data === null && $i < 300);
        if ($data) {
            foreach ($data as &$v) {
                $v = json_decode($v, true);
            }
        } else {
            $data = [];
        }
        return $this->json($data);
    }

    /**
     * http發(fā)送消息
     */
    public function httpSend()
    {
        $n = $this->request->post("n");
        $d = $this->request->post("d");
        if ($n && $d) {
            $this->sendTo($n, json_encode(["v" => 3, "n" => $d]));
            return "1";
        }
        return "0";
    }

    public function __destruct()
    {

    }

    public function __call($name, $arguments)
    {
        return $this->server->$name(...$arguments);
    }

}

到此基本就完成了。你可以去看完整的代碼 : 點(diǎn)這里

其他的一些列子 : https://github.com/lizhichao/...

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

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

相關(guān)文章

  • 以小窺大,從一盞路燈看億萬(wàn)聯(lián)網(wǎng)之路

    摘要:而要實(shí)現(xiàn)物物相連,一共有個(gè)階段性任務(wù),而這個(gè)階段性任務(wù),也伴隨著巨大的挑戰(zhàn)本文分享自華為云社區(qū)云駐共創(chuàng)以小窺大,從一盞路燈看億萬(wàn)物聯(lián)網(wǎng)之路云駐共創(chuàng)以小窺大,從一盞路燈看億萬(wàn)物聯(lián)網(wǎng)之路,作者啟明。 摘要:IoT, Internet of Things,物聯(lián)網(wǎng),顧名思義,是物物相連。而要實(shí)現(xiàn)物...

    appetizerio 評(píng)論0 收藏0
  • 人工智能融入“云”端

    摘要:去年月,阿里云宣布將設(shè)立阿里云廣東研發(fā)中心,招募名云計(jì)算和人工智能工程師,推動(dòng)前沿技術(shù)與廣東產(chǎn)業(yè)融合。吳維剛表示,人工智能與云計(jì)算,兩者不是同一事物,但是相互發(fā)展。近年來(lái),隨著互聯(lián)網(wǎng)和移動(dòng)互聯(lián)網(wǎng)的蓬勃發(fā)展,大數(shù)據(jù)、云計(jì)算、人工智能、物聯(lián)網(wǎng)等新技術(shù)也迎來(lái)了廣闊的發(fā)展空間。去年,阿里云工業(yè)互聯(lián)網(wǎng)全國(guó)總部正式在廣州揭牌成立,阿里云將聯(lián)合廣東本地合作伙伴,共同打造服務(wù)全國(guó)的工業(yè)大腦。去年9月,華為與...

    yacheng 評(píng)論0 收藏0
  • 無(wú)線網(wǎng)絡(luò)技術(shù)學(xué)習(xí)總結(jié)

    摘要:通過(guò)通信線路連入通信子網(wǎng)終端是用戶訪問(wèn)網(wǎng)絡(luò)的界面網(wǎng)絡(luò)操作系統(tǒng)是相對(duì)于主機(jī)操作系統(tǒng)而言的。接收方使用同一擴(kuò)頻碼進(jìn)行擴(kuò)解。 目錄 一、計(jì)算機(jī)網(wǎng)絡(luò) 1.計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)概述 2.計(jì)算機(jī)網(wǎng)絡(luò)分類 3.無(wú)線網(wǎng)絡(luò)分類 二、無(wú)線通信和網(wǎng)絡(luò)仿真技術(shù)基礎(chǔ) 1.基本概念 2.調(diào)制 (1)、概述 (2)、常用方式 ...

    animabear 評(píng)論0 收藏0
  • 如何做一個(gè)自己的開(kāi)源聊天項(xiàng)目?(仿微信)

    摘要:一個(gè)輕量級(jí)高效率的支持聊天與物聯(lián)網(wǎng)的通訊框架從月初到現(xiàn)在已經(jīng)大約已經(jīng)三個(gè)月了,由于一直沒(méi)有時(shí)間與精力很好的維護(hù)這個(gè)項(xiàng)目,心里一直有所歉意。希望本項(xiàng)目對(duì)你有所幫助,我的目標(biāo)暫定,一個(gè)小眾加物聯(lián)網(wǎng)的開(kāi)源通訊項(xiàng)目。 篇幅較長(zhǎng),感謝閱讀。 萬(wàn)事開(kāi)頭難 在我決定做開(kāi)源是因?yàn)樽陨砉ぷ鹘佑|到大多數(shù)的項(xiàng)目都是基于開(kāi)源大佬寫的框架,自覺(jué)慚愧,工作以來(lái)一直忙于業(yè)務(wù)與功能實(shí)現(xiàn),多多少少做過(guò)的幾個(gè)項(xiàng)目也沒(méi)能抽...

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

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

0條評(píng)論

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