Web 服务文件传输,如何添加重试
本文关键字:添加 重试 何添加 服务 文件 传输 Web | 更新日期: 2023-09-27 18:31:52
我有一些代码使用任务通过Web服务传输文件。但是,如果网络断开或发生超时,则会导致文件不完整。我真的在努力使这个服务尽可能可靠,但我真的不确定在哪里开始添加代码,这些代码会在块未发送时捕获,然后尝试多次重新发送它,但也不要发送下一个块直到完成。也许如果它无法重新发送该块超过 X 次,则完全失败并记录事件。
谁能提出什么建议?
Action<Guid, string> action = (smGuid, pubAttFullPath) =>
{
try
{
//Set filename from object
string FileName;
FileName = System.IO.Path.GetFileName(pubAttFullPath.ToString());
//Declare Web Service
TransferFile.TransferFileSoapClient ws_TransferFile = new TransferFile.TransferFileSoapClient();
//
bool transfercompleted = false;
using (FileStream fs = new FileStream(
pubAttFullPath.ToString(),
FileMode.Open,
FileAccess.Read,
FileShare.Read))
{
//Declare Buffers and Counts
byte[] buffer = new byte[49152];
long fileSize = fs.Length;
long totalReadCount = 0;
int readCount;
float percentageComplete = 0;
//Loop and copy file until it changes to not exactly the same byte count as the buffer
//which means the file is about to complete.
while ((readCount = fs.Read(buffer, 0, buffer.Length)) > 0)
{
if (!transfercompleted)
{
totalReadCount += readCount;
byte[] bytesToTransfer;
if (readCount == buffer.Length)
{
//Copy bytes until buffer is different
bytesToTransfer = buffer;
ws_TransferFile.WriteBinaryFile("ABCD", bytesToTransfer, FileName);
percentageComplete = (totalReadCount / (float)fileSize * 100);
percentageComplete = (float)Math.Round(percentageComplete, 2, MidpointRounding.ToEven);
//Update progress to DB
InsertProgress.InsertProgressSoapClient ws_InsertProgress = new InsertProgress.InsertProgressSoapClient();
if (percentageComplete == 10.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 10.0);
}
if (percentageComplete == 20.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 20.0);
}
if (percentageComplete == 30.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 30.0);
}
if (percentageComplete == 40.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 40.0);
}
if (percentageComplete == 50.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 50.0);
}
if (percentageComplete == 60.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 60.0);
}
if (percentageComplete == 70.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 70.0);
}
if (percentageComplete == 80.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 80.0);
}
if (percentageComplete == 90.00)
{
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 90.0);
}
}
else
{
// Only a part is requred to upload,
// copy that part.
List<byte> b = new List<byte>(buffer);
bytesToTransfer = b.GetRange(0, readCount).ToArray();
ws_TransferFile.WriteBinaryFile("ABCD", bytesToTransfer, FileName);
percentageComplete = 100;
//Insert Progress as complete
InsertProgress.InsertProgressSoapClient ws_InsertProgress = new InsertProgress.InsertProgressSoapClient();
ws_InsertProgress.InsertProgressService(smGuid.ToString(), 100);
transfercompleted = true;
fs.Close();
break;
}
}
}
}
}
catch (Exception ex)
{
EventLog.WriteEntry("Application", ex.Message.ToString(), EventLogEntryType.Error);
}
Web 服务对于文件传输来说是个坏主意。我用了几次,但是传输的额外数据量使传输的数据大小比使用简单处理程序发送文件大 1,5-2 倍。处理程序将允许您毫无问题地进行相同的操作。它会导致正确的进度处理和恢复出现很多问题。你真的应该重新考虑使用httphandler。如果你喜欢使用网络服务,这里有一个很好的例子:
http://msdn.microsoft.com/en-us/library/ms172362%28v=vs.85%29.aspx
如果您决定使用 IHttpHandler,请参阅:
http://msdn.microsoft.com/en-us/library/ms228090%28v=vs.100%29.aspx
然后,您可以使用以下代码段来正确处理重试/恢复:
using (Stream stream = new FileStream(
pubAttFullPath.ToString(),
FileMode.Open,
FileAccess.Read,
FileShare.Read))
{
context.Response.AddHeader("Accept-Ranges", "bytes");
context.Response.Buffer = false;
if (context.Request.Headers["Range"] != null)
{
context.Response.StatusCode = 206;
string[] range = context.Request.Headers["Range"].Split(new[] { '=', '-' });
startBytes = Convert.ToInt32(range[1]);
}
int dataToRead = size - startBytes;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Length", dataToRead.ToString());
context.Response.AddHeader("Connection", "Keep-Alive");
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
if (startBytes > 0)
{
context.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, size - 1, size));
stream.Seek(startBytes, SeekOrigin.Begin);
}
while (dataToRead > 0)
{
// Verify that the client is connected.
if (context.Response.IsClientConnected)
{
// Read the data in buffer.
int length = stream.Read(buffer, 0, buffer.Length);
// Write the data to the current output stream.
context.Response.OutputStream.Write(buffer, 0, length);
// Flush the data to the HTML output.
context.Response.Flush();
dataToRead = dataToRead - length;
}
else
{
// prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}