ET框架學習——消息系統之三

       鑑於我之前對於遊戲的網絡開發部分沒有經驗。後面關於ET消息系統的學習都將參考這位朋友Norman_Lin的博客來學習。後面會自己再來調整文章的順序,結構等。

  • CircularBuffer

      這個應該是ET框架中消息相關的類,繼承自Stream類。ChunkSize字段的代表一個字節數組的最大長度。後面兩個隊列應該是用於存儲消息流的。

public int ChunkSize = 8192;
private readonly Queue<byte[]> bufferQueue = new Queue<byte[]>();
private readonly Queue<byte[]> bufferCache = new Queue<byte[]>();
public int LastIndex { get; set; }
public int FirstIndex { get; set; }
private byte[] lastBuffer;

 Length字段的定義和bufferQueue隊列的長度有關,撇開特殊情況不說,結果如下:

 Lenght = (this.bufferQueue.Count - 1) * ChunkSize + this.LastIndex - this.FirstIndex;

     CircularBuffer在實例化是會執行AddLast方法,會將bufferCache隊列中的對頭元素彈出(不存在則創建一個空的元素,長度爲ChunkSize),做兩次賦值:

this.bufferQueue.Enqueue(buffer);
this.lastBuffer = buffer;

       後面還有幾個對bufferQueue隊列做操作的方法,獲取bufferQueue隊列的對頭和隊尾元素,移除對頭元素(重新壓入bufferCache隊列中)。

       後面的幾個方法是對字節數組和Stream間的互相操作,關於Stream類,可以參考這篇文章Write方法用於將steam流寫入到bufferQueue隊列的尾部字節數組中去。在獲取到流中還有數據後,通過一個While循環來寫數據(alreadyCopyCount 和count做判斷)。當字節數組還有位置時,就從流中寫入數據到數組中去。Read方法用於將bufferQueue隊列的頭部字節數組中的數據轉入到流中去。邏輯和Write方法差不多,就是反一下。

// 從stream寫入CircularBuffer
public void Write(Stream stream)
{
    int count = (int)(stream.Length - stream.Position);   // 當前流中剩下的數據長度

    int alreadyCopyCount = 0;   // alreadyCopyCount 代表已經從流中寫入的長度(臨時的)
    while (alreadyCopyCount < count)
    {
        // this.LastIndex是一個遊標,代表已經寫入到數組中的數據長度
        if (this.LastIndex == ChunkSize)
        {
            // 對隊列擴容
            this.AddLast();
            this.LastIndex = 0;
        }
  
        int n = count - alreadyCopyCount;  // n 代表流中還未寫入的數據的長度

        // 數組的長度 - 已經寫入的長度 > 流中還未寫入的數據的長度
        if (ChunkSize - this.LastIndex > n)  
        {
            stream.Read(this.lastBuffer, this.LastIndex, n);
            //  寫入完成後的長度
            this.LastIndex += count - alreadyCopyCount;
            alreadyCopyCount += n;
        }
        else // 數組中的長度不夠,先寫滿,然後擴容再將剩餘的寫入
        {
            stream.Read(this.lastBuffer, this.LastIndex, ChunkSize - this.LastIndex);
            alreadyCopyCount += ChunkSize - this.LastIndex;
            this.LastIndex = ChunkSize;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章