国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

結合promise與websocket的發(fā)布/訂閱模式實踐

vincent_xyb / 2754人閱讀

摘要:結合與的發(fā)布訂閱模式實踐本文初衷最近恰好在公司做了一個聊天室系統(tǒng),所以在系統(tǒng)中做了一下對進行的化改造,所以想寫篇文章總結一下,如果大家有什么更好的方法或者心得感悟,歡迎交流技術??紤]到對并沒什么本質影響,所以本文就不涉及了業(yè)務場景基于的聊天

結合promise與websocket的發(fā)布/訂閱模式實踐 本文初衷

最近恰好在公司做了一個聊天室系統(tǒng),所以在系統(tǒng)中做了一下對websocket進行的promise化改造,所以想寫篇文章總結一下,如果大家有什么更好的方法或者心得感悟,歡迎交流

技術棧

dva + protobuf
考慮到protobuf對websocket并沒什么本質影響,所以本文就不涉及了

業(yè)務場景

基于websocket的聊天室系統(tǒng)

開發(fā)痛點

可能存在按順序觸發(fā)的請求
eg. 刪除req---確認刪除rsp---刷新頁面req---刷新頁面rsp
但由于并非所有的刪除操作后都會刷新頁面,所以考慮是不是可以使用發(fā)布訂閱模式來模擬類似promise的流式操作

存在同一類型請求短時間內多次觸發(fā)時,如何尋找每一條回復信息的發(fā)射源,考慮可以使用promise池+唯一識別碼token來實現(xiàn)

由于dva的異步操作是基于redux-saga的,所以如果可以用promise完成與websocket的互動,那么對于effects中使用yield控制異步流程,也會是一個很好的體驗

實現(xiàn)原理

首先,這一套系統(tǒng)的一切前提是請求的唯一標識符token,前端發(fā)送給服務器之后,服務器必須要把這個token跟數(shù)據(jù)放在一起發(fā)回來才行

本系統(tǒng)的實現(xiàn)原理是

對websocket的send方法進行封裝
發(fā)送階段
1. send執(zhí)行時,先生成一個promise,及其唯一token
2. 將promise的resolve, reject,token,及其他需要的信息放入一個對象,然后推入一個promise池中
3. 執(zhí)行websocket的send方法
4. return 這個promise

接收階段
1. 收到回復消息時,先從promise池中對token進行匹配
2. 根據(jù)回復的狀態(tài)決定執(zhí)行resolve或reject
3. 其他需要的操作
實現(xiàn)代碼
// 每一個實例都只能open一條socket線路,用鎖機制防止重復open
// 本例中不使用心跳檢測,為了方便,只要close是非主動觸發(fā)且前端能捕捉到的(如瀏覽器主動斷開,服務器主動斷開),都會進行自動重連
export class MyWebSocket {
    constructor(url) {
        this.url = url;
    
        // close來源判斷及后續(xù)操作
        this.closeConfig = {
            resolve: null,
            closing: false
        }
        // promise池
        this.promisePool = [];
    }
    
    tokenCheck(req, rsp) {
    // 此處根據(jù)自己的數(shù)據(jù)結構進行tokenCheck的判斷,返回一個boolean
    }
    
    open() {
        return new Promise((resolve, reject) => {
            if (typeof this._websocket === "undefined") {
                this._websocket = new WebSocket(this.url);
                this._websocket.open = (e) => {
                    resolve({e, ws: this});
                };
                this._websocket.onerror = (e) => {
                    reject(e);
                }
            }
            this._websocket.onclose = (e) => {
                // 非主動close
                if (!this.closeConfig.closing) {
                    console.log("reconnect");     
                    // 對應的重連操作     
                }
                // 若手動close,恢復初始狀態(tài)
                this.closeConfig.closing = false;
            }
            
            this._websocket.onmessage = (e) => {
                this.promisePool = this.promisePool.filter((item) => {
                if (this.tokenCheck(req, rsp) {
                  req.resolve(rsp);
                  return false;
                }
                return true;
              })
            };
        });
    }
    
    close() {
        this.closeConfig.closing = true;
        this._websocket.close();        
    }
    // token包含在content中
    send(name, content) {
        return new Promise((resolve, reject) => {
          this.promisePool.push({
            content,
            resolve,
            reject,
            name
          });
          this._websocket.send({name, content});
    });
}

大概流程就是這樣,具體的樣例如下

*test () {
    const ws = new MyWebSocket("www.mywebsocket.com");
    yield ws.open();
    yield ws.send(.....).then(()=>{...});
    yield ws.send(.....).then(()=>{...});
}

本文呢大概就是這么多了,如果有什么錯誤或者遺漏的地方還請大家多多指教

v0.0.2

采取了評論大佬的建議,將promise池從數(shù)組改為對象,直接將token做為key,查詢起來也非常方便

export class MyWebSocket {
    constructor(url) {
        this.url = url;
    
        // close來源判斷及后續(xù)操作
        this.closeConfig = {
            resolve: null,
            closing: false
        }
        // promise池
        this.promisePool = {};
    }
    
    tokenCheck(req, rsp) {
    // 此處根據(jù)自己的數(shù)據(jù)結構進行tokenCheck的判斷,返回一個boolean
    }
    
    open() {
        return new Promise((resolve, reject) => {
            if (typeof this._websocket === "undefined") {
                this._websocket = new WebSocket(this.url);
                this._websocket.open = (e) => {
                    resolve({e, ws: this});
                };
                this._websocket.onerror = (e) => {
                    reject(e);
                }
            }
            this._websocket.onclose = (e) => {
                // 非主動close
                if (!this.closeConfig.closing) {
                    console.log("reconnect");     
                    // 對應的重連操作     
                }
                // 若手動close,恢復初始狀態(tài)
                this.closeConfig.closing = false;
            }
            
            this._websocket.onmessage = (e) => {         
                const key = e.content.token;    
                const req = this.promisePool[key]
                req.resolve(e);
                delete this.promisePool[key];
            };
        });
    }
    
    close() {
        this.closeConfig.closing = true;
        this._websocket.close();
    }
    // token包含在content中
    send(name, content) {
        return new Promise((resolve, reject) => {
          this.promisePool[content.token] = {
            content,
            resolve,
            reject,
            name
          };
          this._websocket.send({name, content});
    });
}

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

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94995.html

相關文章

  • 前端知識點

    摘要:原理對處理函數(shù)進行延時操作,若設定的延時到來之前,再次觸發(fā)事件,則清除上一次的延時操作定時器,重新定時。在目標發(fā)出內容改變的事件后,直接接收事件并作出響應。首先是目標的構造函數(shù),他有個數(shù)組,用于添加觀察者。 關于排序 js中sort函數(shù)的底層實現(xiàn)機制? js中sort內置多種排序算法,是根據(jù)要排序數(shù)的亂序程度來決定使用哪一種排序方法。V8 引擎 sort 函數(shù)只給出了兩種排序 Inse...

    wums 評論0 收藏0
  • GraphQL java工程化實踐

    摘要:我在工程實踐中直接使用類作為對應實體類的。因此我的結論是,此庫并不適用于我的工程實踐。工程實踐中對其應用方式的考慮在的官方教程中建議針對每請求創(chuàng)建新的實例,查詢請求結束則實例們的生命周期結束。 因為自己寫過基于react的前端應用,因此一看到GraphQL就被深深吸引,真是直擊痛點?。》斩碎_發(fā)一直是基于java, Spring的,因此開始研究如何在現(xiàn)有工程框架下加入graphql的支...

    MSchumi 評論0 收藏0
  • 2019年7-8月份前端面試題

    摘要:站點接收到請求后,對請求進行驗證,并確認是受害者的憑證,誤以為是無辜的受害者發(fā)送的請求。函數(shù)內部語句返回的值,會成為方法回調函數(shù)的參數(shù)。 記錄我最近面試缺漏的知識點 css 1.bootstrap如何實現(xiàn)手機PC端自適應 媒體查詢 2.flex布局 父容器:(記得常用屬性) display:flex flex-direction: row | row-reverse | column ...

    shevy 評論0 收藏0
  • 什么是 HTML 5?

    摘要:該區(qū)域代表可以被所控制的畫布。那么現(xiàn)在第二個問題,識別該文檔,這或許不是大部分用戶的需求,但小部分用戶并不意味著人數(shù)少。因此一個基于的請求于標準內提出。 前言 作為程序員,技術的落實與鞏固是必要的,因此想到寫個系列,名為 why what or how 每篇文章試圖解釋清楚一個問題。 這次的 why what or how 主題:現(xiàn)在幾乎所有人都知道了 HTML5 ,那么 H5 到底相...

    zhaofeihao 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<