Have had a similar problem.  Likely the issue is your FTP server needs to increase its timeout settings.  
 

You could try extending the FTP adapter and overriding the delete method as follows:

Method delete(pFilename As %StringpFileDir As %StringAs %Boolean
{
Set tSC=..setFilePath(pFileDir,.tOldDirIf $$$ISERR(tSC$$$LOGSTATUS(tSCQuit }
Set tOK=$S(..%isSFTP:..FTP.DeleteSSH(pFilename),1:..FTP.Delete(pFilename))

if 'tOK

{

if ..Connected set tSC=..Disconnect(1)
Set tSC=..Connect(..ConnectTimeout,1)
Set tOK=$S(..%isSFTP:..FTP.DeleteSSH(pFilename),1:..FTP.Delete(pFilename))

}
Do:'tOK ..disconnectOnNetErr(,1)
If ..Connected Set tSC=..restoreFilePath(tOldDirIf $$$ISERR(tSC$$$LOGSTATUS(tSCQuit }
Quit tOK
}

If tOK returns an error, you failed to delete.  this change will disconnect from the server, reconnect and delete again.  As the most likely issue is you are not connected this will work around your ftp server's timeout.  

The other option is to update your FTP server to have a larger timeout window.

Have had a similar problem.  Likely the issue is your FTP server needs to increase its timeout settings.  
 

You could try extending the FTP adapter and overriding the delete method as follows:

Method delete(pFilename As %String, pFileDir As %String) As %Boolean
{
Set tSC=..setFilePath(pFileDir,.tOldDir) If $$$ISERR(tSC) $$$LOGSTATUS(tSC) Quit 0 }
Set tOK=$S(..%isSFTP:..FTP.DeleteSSH(pFilename),1:..FTP.Delete(pFilename))

if 'tOK

{

if ..Connected set tSC=..Disconnect(1)
Set tSC=..Connect(..ConnectTimeout,1)
Set tOK=$S(..%isSFTP:..FTP.DeleteSSH(pFilename),1:..FTP.Delete(pFilename))

}
Do:'tOK ..disconnectOnNetErr(,1)
If ..Connected Set tSC=..restoreFilePath(tOldDir) If $$$ISERR(tSC) $$$LOGSTATUS(tSC) Quit 0 }
Quit tOK
}

If tOK returns an error, you failed to delete.  this change will disconnect from the server, reconnect and delete again.  As the most likely issue is you are not connected this will work around your ftp server's timeout.  

The other option is to update your FTP server to have a larger timeout window.

In the past I had to do something similar.  I just used a code block to call a classmethod.  The classmethod accepted the context variable by reference.  All you would need to do is loop on the OBX segments and clone the message for each segment which meets your criteria.  Then you would need to remove any extraneous segments.  Once complete you would just need to add each message to an index you created in the context variable.  That way you could loop, transform and send each message in the index in your BP using a foreach.

Are you asking about something like this?  From an Ensemble perspective this is returning something of type  %GlobalCharacterStream.  There is no wrapper class around the %GlobalCharacterStream.  For the consumer of your web service this will appear as a string in the WSDL.
Method SomeMethodName(FacilityID As %String) As  %GlobalCharacterStream [ WebMethod ]
{

// where the response of this method is an object of type %GlobalCharacterStream
quit ##class(SomeClassName).ReturnAStream(FacilityID)
}