protected override IEnumerator ExecuteRoutine() { if (!PreExecuteRoutine()) { yield break; } { //////////////////////////////////////////////////////////////////////////////////////// // Wait for stream to be available //////////////////////////////////////////////////////////////////////////////////////// CurrentState = TransferState.WaitingForStreamToBeAvailable; // if there's already an ongoing transfer to this destination, wait while (s_ongoingOperations.ContainsKey(_connection)) { yield return(null); } s_ongoingOperations.Add(_connection, this); } { //////////////////////////////////////////////////////////////////////////////////////// // Send header to destination (contains essential details about the transfer) //////////////////////////////////////////////////////////////////////////////////////// CurrentState = TransferState.SendingHeader; NetMessageViaStreamChannelHeader header = new NetMessageViaStreamChannelHeader() { TransferId = _transferId, DataSize = _data.Length, Description = Description, }; _sessionInterface.SendNetMessage(header, _connection); } { //////////////////////////////////////////////////////////////////////////////////////// // Await the 'ready!' reponse //////////////////////////////////////////////////////////////////////////////////////// var readyResponse = DisposeOnTerminate(new AwaitNetMessage <NetMessageViaStreamReady>(_sessionInterface, (source, response) => { return(source == _connection && response.TransferId == _transferId); })); CurrentState = TransferState.WaitingForReady; yield return(readyResponse.WaitForResponse()); } { //////////////////////////////////////////////////////////////////////////////////////// // Send data //////////////////////////////////////////////////////////////////////////////////////// CurrentState = TransferState.SendingData; var streamChannel = _sessionInterface.NetworkInterface.GetStreamChannel(StreamChannelType.LargeDataTransfer); // listen for progress update _sessionInterface.RegisterNetMessageReceiver <NetMessageViaStreamUpdate>(OnProgressUpdate); _sessionInterface.NetworkInterface.StreamDataAborted += OnStreamAborted; _connection.StreamBytes(streamChannel, _data); } { //////////////////////////////////////////////////////////////////////////////////////// // Await reponse from the destination that indicates that it received all of the data //////////////////////////////////////////////////////////////////////////////////////// var ackResponse = DisposeOnTerminate(new AwaitNetMessage <NetMessageViaStreamACK>(_sessionInterface, (source, response) => { return(source == _connection && response.TransferId == _transferId); })); CurrentState = TransferState.WaitingCompleteDataACK; yield return(ackResponse.WaitForResponse()); } TerminateWithSuccess(); }
private const float PROGRESS_UPDATE_INTERVAL = 2f; // update the uploader on the progress every 2s public ReceiveViaStreamChannelOperation(NetMessageViaStreamChannelHeader transferHeader, INetworkInterfaceConnection source, SessionInterface sessionInterface) : base(sessionInterface, source, transferHeader.TransferId) { _transferHeader = transferHeader; CurrentState = TransferState.NotStarted; }