優化gateway支援wss協議

wavebossy6666發表於2020-11-20

程式碼備份錄—— workman-gateway 支援ssl 遇到的問題,以及解決方式

我的目標

支援ssl 協議,使得小程式能使用

伺服器情況

測試服:公網IP 55.55.55.55  內網IP192.168.1.1 【通過nginx實現】

通過官方指導配置,在gateway內配置ssl相關內容
負載均衡(伺服器AB已通過阿里雲slb 做了負載均衡,並已監聽443埠)
伺服器A :公網IP 66.66.66.61  內網IP192.168.0.1
伺服器B :公網IP 99.99.99.91  內網IP192.168.0.2

上一篇和這篇都漏記錄了一個bindUid 方法

public function bindUid 方法(Request $request){
    // 商家客戶端進行繫結
    if("business" == $request["type"]){
    // $request["id"] = 商家繫結後臺登入的手機號,且唯一
    Gateway::bindUid($request["client_id"],$request["id"]);
    }

    return json_encode([Gateway::getClientIdByUid($request['id'])]);
}

官方配置

內容來自:start_gateway.php 檔案部分內容

// 證照最好是申請的證照
$context = array(
    // 更多ssl選項請參考手冊 http://php.net/manual/zh/context.ssl.php
    'ssl' => array(
        // 請使用絕對路徑
        'local_cert'                 => 'ssl/*****.pem', // 也可以是crt檔案
        'local_pk'                   => 'ssl/*****.key',
        'verify_peer'               => false,
        // 'allow_self_signed' => true, //如果是自簽名證照需要開啟此選項
    )
);
// 原先是這裡監聽了7373埠,此處註釋掉,改為443//$gateway = new Gateway("Websocket://0.0.0.0:7373");

// websocket協議(埠任意,只要沒有被其它程式佔用就行)
$gateway = new Gateway("websocket://0.0.0.0:443", $context);
// 開啟SSL,websocket+SSL 即wss
$gateway->transport = 'ssl';

****其他不變****

使用nginx配置

    1、啟動gateway 監聽websocket 埠 7373
    2、nginx 配置反向代理,轉到7373埠 【域名都是測試服的域名,證照一致】

    核心nginx配置
    map  $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    upstream websocket { 
        server 66.66.66.61:7373; #當前伺服器的IP
    }
    server
    {
        ****
        #SSL-END
        location /wss
        {
                proxy_pass http://66.66.66.61:7373;#當前伺服器的IP
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Real-IP $remote_addr;
        }
    }

域名繫結

新增記錄
1、domain.com ==正常解析到第一臺ip==> 66.66.66.61
2、申請 domain.com => ssl 拿到證照

客戶端繫結

程式碼說明
2new wss協議
啟動ws連結
onopen
{"type":"init","client_id":"c0a8a0cc090800000007"}
收到workman返回的client_id,準備繫結laravel
開始繫結client_id
繫結成功 [Array(1)]

<script type="text/javascript">

    var ws;
    var client_id ;

    function connect() {
        // 此處的domain.com 是指向register的那臺伺服器(上方伺服器有記錄)
        ws = new WebSocket("wss://domain.com");
        ws.onopen = onopen;
        ws.onmessage = onmessage;
        ws.onclose = function() {
            console.log("連線關閉,定時重連");
            connect();
        };
        ws.onerror = function() {
            console.log("出現錯誤");
        };
    }
    function onmessage(e) {
        console.log("服務端推送",e.data);
        var data = JSON.parse(e.data);
        client_id = data['client_id'];
        switch(data['type']){
            // 繫結 client_id
            case 'init':
                // 客戶端ID繫結
                console.log("收到workman返回的client_id,準備繫結laravel");
                loginInit(data);
                break;
            // 服務端 ping 客戶端
            case 'ping':
                ws.send('{"type":"ping"}');
                break;
        }
    }
    function loginInit(data) {
        $.ajax({
            url:"api/wss/bindUid",
            type: "post",
            data:{
                id:"business",
                type:"business",
                client_id:data['client_id']
            },
            cache:false,
            dataType: "json",
            beforeSend:function(XMLHttpRequest){
                console.log("開始繫結client_id");
            },
            success:function(pay){
                console.log("繫結成功",pay);
            },
            error: function (XMLHttpRequest,ex) {
            }
        });
    }
    function onopen() {

    } 
    setTimeout(function () {
        console.log("啟動ws連線");
        connect();
    },1000);
</script>

遇到的問題,放在最後

nginx 反向代理到websocket埠,也是用的http 

心得

結合上一篇,已在架構上實現多臺負載均衡,並且支援 wss協議

官網指導的部署方式

workman官方部署wss方式

本作品採用《CC 協議》,轉載必須註明作者和本文連結
朝著夢,踏平坎坷

相關文章