/// <summary> /// trigger for the registered {@code MSRPSessionListener} callback. /// </summary> /// <param name="session"></param> /// <param name="outgoingMessage"></param> public void TriggerUpdateSendStatus(Session session, OutgoingMessage outgoingMessage) { _logger.Debug("Called the triggerUpdateSendStatus hook"); _myListener.UpdateSendStatus(session, outgoingMessage, outgoingMessage.SentBytes); }
/// <summary> /// Method used by the connection object to retrieve a byte array of data /// to be sent by the connection. /// /// 3 mechanisms are active here: /// - 1 piggyback multiple transactions to send into the byte array. /// - 2 split large data over multiple byte-array blocks /// - 3 interrupt transactions that contain endline-data in the content /// (and split into multiple transactions, using the validator). /// /// It is also at this level that the sending of bytes is accounted for /// purposes of triggering the sendUpdateStatus and the prioritiser /// </summary> /// <param name="outData">the byte array to fill with data to be sent</param> /// <returns>the number of bytes filled on outData</returns> public int GetDataToSend(byte[] outData) { int byteCounter = 0; //Variable that accounts the number of bytes per transaction sent int bytesToAccount = 0; lock (_transactionsToSendLock) { while (byteCounter < outData.Length && HasDataToSend) { Transaction t = _transactionsToSend[0]; _outgoingDataValidator.Init(t.TransactionId); bool stopTransmission = false; while (byteCounter < outData.Length && !stopTransmission) { if (t.HasData) { // if we are still transmitting data int result = t.GetData(outData, byteCounter); byteCounter += result; bytesToAccount += result; } else { // Let's check to see if we should transmit the end of line if (t.HasEndLine) { /* * the first time we get here we should check if the * end-line was found, and if it was we should rewind, * interrupt the transaction and set the bytesToAccount * back the appropriate positions and also the index i * we can also do the reset of the outgoingDataValidator * because we have for certain that the end-line won't * appear again on the content before the transaction * finishes */ _outgoingDataValidator.Parse(outData, byteCounter); _outgoingDataValidator.Reset(); if (_outgoingDataValidator.DataHasEndLine) { int rewindAmount = _outgoingDataValidator.Amount2Rewind(); t.Rewind(rewindAmount); t.Interrupt(); byteCounter -= rewindAmount; bytesToAccount -= rewindAmount; continue; } int nrBytes = t.GetEndLine(outData, byteCounter); byteCounter += nrBytes; bytesToAccount += nrBytes; } else { // Removing the given transaction from the queue of // transactions to send RemoveTransactionToSend(t); // we should also reset the outgoingDataValidator, so // that future calls to the parser won't misjudge the //correct end-line as an end-line on the body content. _outgoingDataValidator.Reset(); stopTransmission = true; // let's get the next transaction if any } } }// end of transaction while stopTransmission = false; /* * the buffer is full and or the transaction has been removed from * the list of transactions to send and if that was the case the * outgoingValidator won't make a false positive because it has been * reset */ _outgoingDataValidator.Parse(outData, byteCounter); if (_outgoingDataValidator.DataHasEndLine) { int rewindAmount = _outgoingDataValidator.Amount2Rewind(); t.Rewind(rewindAmount); t.Interrupt(); byteCounter -= rewindAmount; bytesToAccount -= rewindAmount; int nrBytes = t.GetEndLine(outData, byteCounter); byteCounter += nrBytes; bytesToAccount += nrBytes; RemoveTransactionToSend(t); _outgoingDataValidator.Reset(); } // account for the bytes sent from this transaction if they should // be accounted for if (!t.IsIncomingResponse && t.TransactionType == TransactionType.SEND && !t.HasResponse) { // reporting the sent update status seen that this is an // outgoing send request OutgoingMessage transactionMessage = (OutgoingMessage)t.Message; if (transactionMessage != null) { transactionMessage.ReportMechanism.CountSentBodyBytes(transactionMessage, bytesToAccount); bytesToAccount = 0; } } }// end of main while, the one that goes across transactions } return(byteCounter); }