Пример #1
0
        private void PipelineReceive(SocketToken token)
        {
            var fromCursor = 0;

            /*
             *      read data from receiveBuffer by moving fromCursor.
             */
            while (true)
            {
                var currentCommand = token.currentCommands.Peek();
                var result         = DisquuunAPI.ScanBuffer(currentCommand, token.receiveBuffer, fromCursor, token.readableDataLength, socketId);

                if (result.isDone)
                {
                    token.AsyncCallback(currentCommand, result.data);

                    // deque as read done.
                    token.currentCommands.Dequeue();

                    if (token.currentCommands.Count == 0)
                    {
                        // pipelining is over.
                        switch (token.socketState)
                        {
                        case SocketState.BUSY: {
                            token.socketState = SocketState.RECEIVED;
                            break;
                        }

                        case SocketState.SENDED: {
                            token.socketState = SocketState.OPENED;
                            SocketReloaded(this);
                            break;
                        }

                        default: {
                            break;
                        }
                        }
                        return;
                    }

                    // commands are still remained.

                    // got all data is just consumed. get rest from outside.
                    if (fromCursor == token.readableDataLength)
                    {
                        StartContinueReceiving(token, 0);
                        return;
                    }

                    // rest pipeline commands and received data is exists in buffer.
                    fromCursor = result.cursor;
                    continue;
                }

                /*
                 *      reading is not completed. the fragment of command exists.
                 */

                var fragmentDataLength = token.readableDataLength - fromCursor;

                // move fragment data to head of buffer.
                Buffer.BlockCopy(token.receiveBuffer, fromCursor, token.receiveBuffer, 0, fragmentDataLength);

                StartContinueReceiving(token, fragmentDataLength);
                break;
            }
        }
Пример #2
0
        private void LoopOrAsyncReceive(SocketToken token)
        {
            var currentCommand = token.currentCommands.Peek();
            var result         = DisquuunAPI.ScanBuffer(currentCommand, token.receiveBuffer, 0, token.readableDataLength, socketId);

            if (result.isDone && result.cursor == token.readableDataLength)
            {
                // update continuation status.
                token.continuation = token.AsyncCallback(currentCommand, result.data);

                if (token.continuation)
                {
                    switch (token.socketState)
                    {
                    case SocketState.BUSY: {
                        token.socketState = SocketState.RECEIVED;
                        break;
                    }

                    case SocketState.SENDED: {
                        // ready for next loop receive.
                        token.readableDataLength = 0;
                        token.receiveArgs.SetBuffer(token.receiveBuffer, 0, token.receiveBuffer.Length);
                        if (!token.socket.ReceiveAsync(token.receiveArgs))
                        {
                            OnReceived(token.socket, token.receiveArgs);
                        }

                        try {
                            token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length);
                        } catch {
                            // renew. potential error is exists and should avoid this error.
                            var sendArgs = new SocketAsyncEventArgs();
                            sendArgs.RemoteEndPoint = token.receiveArgs.RemoteEndPoint;
                            sendArgs.Completed     += new EventHandler <SocketAsyncEventArgs>(OnSend);
                            sendArgs.UserToken      = token;
                            token.sendArgs          = sendArgs;
                            token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length);
                        }

                        if (!token.socket.SendAsync(token.sendArgs))
                        {
                            OnSend(token.socket, token.sendArgs);
                        }

                        break;
                    }

                    default: {
                        // closing or other state. should close.
                        break;
                    }
                    }
                    return;
                }

                // end of loop or end of async.

                switch (token.socketState)
                {
                case SocketState.BUSY: {
                    token.socketState = SocketState.RECEIVED;
                    break;
                }

                case SocketState.SENDED: {
                    token.socketState = SocketState.OPENED;
                    SocketReloaded(this);
                    break;
                }

                default: {
                    break;
                }
                }
                return;
            }

            // not yet received all data.
            // continue receiving.

            StartContinueReceiving(token, token.readableDataLength);
        }
Пример #3
0
        private void StartReceiveAndSendDataAsync(DisqueCommand[] commands, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback)
        {
#if LOGIC_BENCH
            {
                socketToken.currentCommands     = commands;
                socketToken.currentSendingBytes = data;
                socketToken.AsyncCallback       = Callback;

                socketToken.isPipeline = false;
                if (1 < commands.Length)
                {
                    socketToken.isPipeline = true;
                    pipelineIndex          = 0;

                    // -> PipelineReceive(token);
                    {
                        foreach (var command in commands)
                        {
                            var result = new DisquuunResult[0];
                            socketToken.AsyncCallback(command, result);
                        }
                        socketToken.socketState = SocketState.OPENED;
                        SocketReloaded(this);
                    }
                }
                else
                {
                    // OnSend -> token.socketState = SocketState.SENDED;
                    // receive -> Bench_LoopOrAsyncReceive(token);
                    {
                        Bench_LoopOrAsyncReceive(commands[0]);
                    }
                }
                return;
            }
#endif

            // ready for receive.
            socketToken.readableDataLength = 0;

            socketToken.receiveArgs.SetBuffer(socketToken.receiveBuffer, 0, socketToken.receiveBuffer.Length);
            if (!socketToken.socket.ReceiveAsync(socketToken.receiveArgs))
            {
                OnReceived(socketToken.socket, socketToken.receiveArgs);
            }

            // if multiple commands exist, set as pipeline.
            socketToken.isPipeline = false;
            if (1 < commands.Length)
            {
                socketToken.isPipeline = true;
                pipelineIndex          = 0;
            }

            socketToken.currentCommands     = commands;
            socketToken.currentSendingBytes = data;
            socketToken.AsyncCallback       = Callback;

            try
            {
                socketToken.sendArgs.SetBuffer(data, 0, data.Length);
            }
            catch
            {
                // renew. potential error is exists and should avoid this error.
                var sendArgs = new SocketAsyncEventArgs();
                sendArgs.RemoteEndPoint = socketToken.receiveArgs.RemoteEndPoint;
                sendArgs.Completed     += new EventHandler <SocketAsyncEventArgs>(OnSend);
                sendArgs.UserToken      = socketToken;

                socketToken.sendArgs = sendArgs;
                socketToken.sendArgs.SetBuffer(data, 0, data.Length);
            }

            if (!socketToken.socket.SendAsync(socketToken.sendArgs))
            {
                OnSend(socketToken.socket, socketToken.sendArgs);
            }
        }