Swoole學習之網絡通訊引擎WebSocket服務(五)

1、Websocket基本概述

WebSocket協議是基於TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通訊-容許服務器主動發信息給客戶端php

爲何須要WebSocket?
缺陷:HTTP的通訊只能由客戶端發起html

WebSocket的特色:web

  • 創建在TCP協議之上
  • 性能開銷小通訊高效
  • 客戶端能夠與任意服務器通訊
  • 協議標識符ws wss
  • 持久化網絡通訊協議

2、代碼實現

websocket服務端

ws_server.phpdocker

<?php

//建立websocket服務器對象,監聽0.0.0.0:80端口
$ws = new swoole_websocket_server("0.0.0.0", 80);

//監聽WebSocket鏈接打開事件
$ws->on('open', function ($ws, $request) {
    var_dump($request->fd, $request->get, $request->server);
    $ws->push($request->fd, "hello, welcome\n");
});

//監聽WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
    echo "Message: {$frame->data}\n";
    $ws->push($frame->fd, "server: {$frame->data}");
});

//監聽WebSocket鏈接關閉事件
$ws->on('close', function ($ws, $fd) {
    echo "client-{$fd} is closed\n";
});

$ws->start();

由於咱們是在docker 容器中,因此,咱們使用 80 端口,這樣能夠在宿主機經過以前作的端口映射,就能夠在宿主機瀏覽器訪問該服務。瀏覽器

宿主機容器映射的端口查看:bash

➜  ~ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                        NAMES
5ee6bfcc1310        7698f               "/bin/bash"         46 hours ago        Up 30 hours         0.0.0.0:2221->22/tcp, 0.0.0.0:8880->80/tcp   confident_jones

客戶端靜態頁面

靜態頁面路徑:/work/study/code/swoole/demo/static服務器

ws_client.htmlwebsocket

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket TEST</title>
</head>
<body>
<h1>Swoole-TEST</h1>
<script>
    var wsUrl = "ws://0.0.0.0:8880";
    var websocket = new WebSocket(wsUrl);

    // 實例化onopen對象
    websocket.onopen = function(evt){
        console.log("connected-swoole-success")
         websocket.send("Hello-Lily"); // 發送信息給服務端
    }

    // 實例化 onmessage
    websocket.onmessage = function(evt){
        console.log("ws-server-return-data"+evt.data)
    }

    // 實例化 onclose
    websocket.onclose = function(evt){
        console.log("close")
    }

    // onerror
    websocket.onerror = function (evt) {
        console.log("error:" + evt.data)
    }


</script>

</body>
</html>

宿主機瀏覽器訪問:swoole

clipboard.png

3、WebSocket服務優化

咱們能夠看到,上邊的 ws_server.php 代碼是面向過程代碼,不夠優雅,這裏咱們能夠把這些方法封裝起來,用面向對象的思路來優化。網絡

ws.php

<?php

/**
 * WS 優化基礎類庫
 */

class Ws
{
    public $ws = null;

    CONST HOST = "0.0.0.0";
    CONST PORT = 80;

    public function __construct()
    {
        $this->ws = new swoole_websocket_server(static::HOST, static::PORT);

        $this->ws->on("open", [$this, "onOpen"]);
        $this->ws->on("message", [$this, "onMessage"]);
        $this->ws->on("close", [$this, "onClose"]);

        $this->ws->start();
    }

    /**
     * 監聽ws鏈接事件
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request)
    {
        var_dump($request->fd);
    }

    /**
     * 監聽ws鏈接消息
     * @param $ws
     * @param $frame
     */
    public function onMessage($ws, $frame)
    {
        echo "ser-push-message:{$frame->data}\n";

        $ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));

    }

    /**
     * 監聽WebSocket鏈接關閉事件
     *
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd)
    {
        echo "clientid:{$fd} closed \n";
    }
}

$ws_obj = new Ws();

經過面向對象封裝,上邊的代碼優雅了不少哈~

相關文章
相關標籤/搜索