示例#1
0
        public void OnReloaded(DisquuunSocket reloadedSocket)
        {
            lock (lockObject) {
                if (stackSocket.IsQueued())
                {
                    if (reloadedSocket.IsChoosable())
                    {
                        reloadedSocket.SetBusy();

                        var commandAndData = stackSocket.Dequeue();

                        if (commandAndData.data.Length == 0)
                        {
                            Disquuun.Log("OnReloaded len = 0.", true);
                        }
                        switch (commandAndData.executeType)
                        {
                        case DisquuunExecuteType.ASYNC: {
                            reloadedSocket.Async(commandAndData.command, commandAndData.data, commandAndData.Callback);
                            return;
                        }

                        case DisquuunExecuteType.LOOP: {
                            reloadedSocket.Loop(commandAndData.command, commandAndData.data, commandAndData.Callback);
                            return;
                        }
                        }
                    }
                }
            }
        }
        private void OnSend(object unused, SocketAsyncEventArgs args)
        {
            try {
                switch (args.SocketError)
                {
                case SocketError.Success: {
                    var token = args.UserToken as SocketToken;


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

                    case SocketState.RECEIVED: {
                        if (token.continuation)
                        {
                            // 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);
                            }

                            token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length);
                            if (!token.socket.SendAsync(token.sendArgs))
                            {
                                OnSend(token.socket, token.sendArgs);
                            }
                            return;
                        }

                        token.socketState = SocketState.OPENED;
                        SocketReloaded(this);
                        return;
                    }
                    }
                    return;
                }

                default: {
                    Disquuun.Log("onsend error, " + args.SocketError, true);
                    // if (Error != null) {
                    //  var error = new Exception("send error:" + socketError.ToString());
                    //  Error(error);
                    // }
                    return;
                }
                }
            } catch (Exception e) {
                Disquuun.Log("OnSend e:" + e, true);
            }
        }
 public virtual void Async(DisqueCommand command, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback)
 {
     lock (stackLockObject) {
         try {
             this.stackedDataQueue.Enqueue(new StackCommandData(DisquuunExecuteType.ASYNC, command, data, Callback));
         } catch (Exception e) {
             Disquuun.Log("failed to start async:" + e);
         }
     }
 }
 public void Disconnect()
 {
     try {
         socketToken.socketState = SocketState.CLOSING;
         External.Disconnect(socketToken, null);
         socketToken.socketState = SocketState.CLOSED;
     } catch (Exception e) {
         Disquuun.Log("Disconnect e:" + e.Message, true);
     }
     return;
 }
        /*
         *      Core methods of Disquuun.
         */

        /**
         *      method for Sync execution of specific Disque command.
         *      DEPRECATED. only use for testing.
         */
        public override DisquuunResult[] DEPRECATED_Sync(DisqueCommand command, byte[] data)
        {
            try {
                socketToken.socket.Send(data);

                var currentLength = 0;
                var scanResult    = new DisquuunAPI.ScanResult(false);

                while (true)
                {
                    // waiting for head of transferring data or rest of data.
                    socketToken.socket.Receive(socketToken.receiveBuffer, currentLength, 1, SocketFlags.None);
                    currentLength = currentLength + 1;

                    var available      = socketToken.socket.Available;
                    var readableLength = currentLength + available;
                    {
                        if (socketToken.receiveBuffer.Length < readableLength)
                        {
                            // Disquuun.Log("サイズオーバーしてる " + socketToken.receiveBuffer.Length + " vs:" + readableLength);
                            Array.Resize(ref socketToken.receiveBuffer, readableLength);
                        }
                    }

                    // read rest.
                    socketToken.socket.Receive(socketToken.receiveBuffer, currentLength, available, SocketFlags.None);
                    currentLength = currentLength + available;

                    scanResult = DisquuunAPI.ScanBuffer(command, socketToken.receiveBuffer, currentLength, socketId);
                    if (scanResult.cursor == currentLength)
                    {
                        break;
                    }

                    // continue reading data from socket.
                    // if need, prepare for next 1 byte.
                    if (socketToken.receiveBuffer.Length == readableLength)
                    {
                        Array.Resize(ref socketToken.receiveBuffer, socketToken.receiveBuffer.Length + 1);
                    }
                }

                socketToken.socketState = SocketState.OPENED;
                return(scanResult.data);
            }catch (Exception e) {
                Disquuun.Log("e:" + e, true);
                throw e;
            }
        }
        /*
         *      default pooled socket + disposable socket shared
         */
        private void StartReceiveAndSendDataAsync(DisqueCommand command, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback)
        {
            try {
                // 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);
                }

                socketToken.currentCommand      = command;
                socketToken.currentSendingBytes = data;
                socketToken.AsyncCallback       = Callback;

                try {
                    socketToken.sendArgs.SetBuffer(data, 0, data.Length);
                } catch (Exception e) {
                    Disquuun.Log("StartReceiveAndSendDataAsync before error,", true);
                    Disquuun.Log("sendArgs setBuffer error:" + e.Message);

                    // renew. potential error is exists and should avoid this error.
                    var endPoint = socketToken.sendArgs.RemoteEndPoint;
                    socketToken.sendArgs = new SocketAsyncEventArgs();

                    socketToken.sendArgs.RemoteEndPoint = endPoint;
                    socketToken.sendArgs.Completed     += new EventHandler <SocketAsyncEventArgs>(OnSend);
                }
                if (!socketToken.socket.SendAsync(socketToken.sendArgs))
                {
                    OnSend(socketToken.socket, socketToken.sendArgs);
                }
            } catch (Exception e1) {
                Disquuun.Log("StartReceiveAndSendDataAsync error:" + e1.Message, true);
            }
        }
        private void OnReceived(object unused, SocketAsyncEventArgs args)
        {
            var token = (SocketToken)args.UserToken;

            if (args.SocketError != SocketError.Success)
            {
                switch (token.socketState)
                {
                case SocketState.CLOSING:
                case SocketState.CLOSED: {
                    // already closing, ignore.
                    return;
                }

                default: {
                    switch (args.SocketError)
                    {
                    case SocketError.ConnectionReset: {
                        Disquuun.Log("ConnectionResetが出てる. " + " token.socketState:" + token.socketState, true);
                        break;
                    }

                    default: {
                        Disquuun.Log("onReceive default token.socketState:" + token.socketState + " error:" + args.SocketError, true);
                        break;
                    }
                    }

                    Disconnect();

                    var e1 = new Exception("receive status is not good.");
                    SocketClosed(this, "failed to receive.", e1);
                    return;
                }
                }
            }

            if (args.BytesTransferred == 0)
            {
                return;
            }

            var bytesAmount = args.BytesTransferred;

            // update as read completed.
            token.readableDataLength = token.readableDataLength + bytesAmount;

            var result = DisquuunAPI.ScanBuffer(token.currentCommand, token.receiveBuffer, token.readableDataLength, socketId);

            // data is totally read and executable.
            if (result.cursor == token.readableDataLength)
            {
                var continuation = token.AsyncCallback(token.currentCommand, result.data);

                // update continuation status.
                token.continuation = continuation;

                if (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 {
                            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.

            /*
             *      note that,
             *
             *      SetBuffer([buffer], offset, count)'s "count" is, actually not count.
             *
             *      it's "offset" is "offset of receiving-data-window against buffer",
             *      but the "count" is actually "size limitation of next receivable data size".
             *
             *      this "size" should be smaller than size of current bufferSize - offset && larger than 0.
             *
             *      e.g.
             *              if buffer is buffer[10], offset can set 0 ~ 8, and,
             *              count should be 9 ~ 1.
             *
             *      if vaiolate to this rule, ReceiveAsync never receive data. not good behaviour.
             *
             *      and, the "buffer" is treated as pointer. this API treats the pointer of buffer directly.
             *      this means, when the byteTransferred is reaching to the size of "buffer", then you resize it to proper size,
             *
             *      you should re-set the buffer's pointer by using SetBuffer API.
             *
             *
             *      actually, SetBuffer's parameters are below.
             *
             *      socket.SetBuffer([bufferAsPointer], additionalDataOffset, receiveSizeLimit)
             */

            var nextAdditionalBytesLength = token.socket.Available;

            if (token.readableDataLength == token.receiveBuffer.Length)
            {
                Array.Resize(ref token.receiveBuffer, token.receiveArgs.Buffer.Length + nextAdditionalBytesLength);
            }

            var receivableCount = token.receiveBuffer.Length - token.readableDataLength;

            token.receiveArgs.SetBuffer(token.receiveBuffer, token.readableDataLength, receivableCount);

            if (!token.socket.ReceiveAsync(token.receiveArgs))
            {
                OnReceived(token.socket, token.receiveArgs);
            }
        }