public Message EndReceive(IAsyncResult result)
        {
            byte[] data = ReadDataAsyncResultClient.End(result);
            if (data == null)
            {
                return(null);
            }

            return(this.DecodeMessage(data));
        }
        void wsClient_DataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data == null)
            {
                logger.Error("null data received.");
                return;
            }

            // get length data
            if (this.bufferPos == -1)
            {
                if (e.Data.Length != 4)
                {
                    logger.ErrorFormat("error length data. [{0}]", e.Data.Length);
                    return;
                }

                // length data
                this.expectLen  = BitConverter.ToInt32(e.Data, 0);
                this.recvBuffer = new byte[this.expectLen];
                this.bufferPos  = 0;

                return;
            }

            // fill buffer
            Array.Copy(e.Data, 0, this.recvBuffer, this.bufferPos, e.Data.Length);
            this.bufferPos += e.Data.Length;
            if (this.bufferPos < this.expectLen)
            {
                return; // not full
            }
            this.bufferPos = -1;

            // complete the read async result
            lock (this.readDataAsyncResultQueue)
            {
                if (this.readDataAsyncResultQueue.Count > 0)
                {
                    ReadDataAsyncResultClient result = this.readDataAsyncResultQueue.Dequeue();
                    result.Complete(false, this.recvBuffer);

                    return;
                }
            }

            // there is no read data async result, cache the received data
            lock (this.receivedDataQueue)
            {
                this.receivedDataQueue.Enqueue(this.recvBuffer);
            }
        }
        public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
        {
            ReadDataAsyncResultClient result = new ReadDataAsyncResultClient(callback, state);

            // if there is already data received, complete the read async result immediately
            lock (this.receivedDataQueue)
            {
                if (this.receivedDataQueue.Count > 0)
                {
                    result.Complete(true, this.receivedDataQueue.Dequeue());

                    return(result);
                }
            }

            // there is no data received, wait for data arrive
            lock (this.readDataAsyncResultQueue)
            {
                this.readDataAsyncResultQueue.Enqueue(result);
            }

            return(result);
        }
        public static byte[] End(IAsyncResult result)
        {
            ReadDataAsyncResultClient thisPtr = AsyncResult.End <ReadDataAsyncResultClient>(result);

            return(thisPtr.data);
        }