gpt4 book ai didi

c# - 为什么在断点上过早继续会使我的服务器发送无效响应

转载 作者:太空宇宙 更新时间:2023-11-03 10:41:24 25 4
gpt4 key购买 nike

我正在通过 IIS 为 WCF 服务中的范围请求返回一个视频文件。

代码的结尾是这样的:

WriteResponseHeaders(stuff);
while (remainingBytes > 0)
{
if (response.IsClientConnected) // response is a System.Web.HttpResponse
{
int chunkSize = stream.Read(buffer, 0, 10240 < remainingBytes ? 10240 : remainingBytes);
response.OutputStream.Write(buffer, 0, chunkSize);
remainingBytes -= chunkSize;
response.Flush();
}
else
{
return;
}
}

在 Firefox、Internet Explorer 和 Opera 中它可以正常工作。在 Chrome 中,视频会在结束前停止播放一段时间。 Fiddler 显示 504 错误:

[Fiddler] ReadResponse() failed: The server did not return a response for this request. Server returned 16556397 bytes.

如果我在循环之后设置一个断点,让程序停在那里直到视频播放超过其停止点,Chrome 将毫无问题地播放完整视频,而 Fiddler 将显示带有所有正确标题的响应等等。在该断点和调用结束之间执行的唯一代码是刷新日志流。

作为测试,我坚持:

while (response.IsClientConnected)
{
System.Threading.Thread.Sleep(1000);
}

在所有浏览器中循环和播放都正常。我的回复在 Fiddler 中看起来也不错。当然,这有太多问题,不是一个合适的解决方案,但它似乎告诉我,这是一个时间问题,而不是行为问题。

为什么允许代码过早超过这一点会导致问题,我如何防止它这样做?

最佳答案

尝试返回一个 Stream 而不是写入 response.OutputStream。

[ServiceContract]
public interface IStreamingService
{
[OperationContract]
[WebGet(BodyStyle=WebMessageBodyStyle.Bare, UriTemplate = "/video?id={id}")]
Stream GetVideo(string id);
}

public class StreamingService : IStreamingService
{
public System.IO.Stream GetVideo(string id)
{
Stream stream = File.OpenRead("c:\\Temp\\Video.mp4");
//WriteResponseHeaders(stuff);
return stream;
}
}

更新:

如果你想支持查找,你可以将 block 复制到 byte[] 并返回 MemoryStream,或者你可以将你的流包装在只返回完整文件的一部分的代理中。

public class PartialStream : Stream
{
private Stream underlying;

private long offset;

private long length;

public PartialStream(Stream underlying, long offset, long length)
{
this.underlying = underlying;
this.offset = offset;
if (offset + length > underlying.Length) {
this.length = underlying.Length - offset;
} else {
this.length = length;
}

this.underlying.Seek(offset, SeekOrigin.Begin);
}

public override bool CanRead { get { return true; } }

public override bool CanSeek { get { return false; } }

public override bool CanWrite { get { return false; } }

public override void Flush()
{
throw new NotSupportedException();
}

public override long Length
{
get { return this.length; }
}

public override long Position
{
get
{
return this.underlying.Position - offset;
}
set
{
this.underlying.Position = offset + Math.Min(value,this.length) ;
}
}

public override int Read(byte[] buffer, int offset, int count)
{
if (this.Position + offset >= this.length)
return 0;

if (this.Position + offset + count > this.length) {
count = (int)(this.length - this.Position - offset);
}


return underlying.Read(buffer, offset, count);
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.underlying.Dispose();
}

public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}

public override void SetLength(long value)
{
throw new NotImplementedException();
}

public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}

}

而且您必须遵守 Range 请求 header 。

public System.IO.Stream GetVideo(string id)
{
RangeHeaderValue rangeHeader;

bool hasRangeHeader = RangeHeaderValue.TryParse(
WebOperationContext.Current.IncomingRequest.Headers["Range"],
out rangeHeader);

var response = WebOperationContext.Current.OutgoingResponse;
Stream stream = File.OpenRead("c:\\Temp\\Video.mp4");

var offset = hasRangeHeader ? rangeHeader.Ranges.First().From.Value : 0;

response.Headers.Add("Accept-Ranges", "bytes");
response.ContentType = "video/mp4";

if (hasRangeHeader) {
response.StatusCode = System.Net.HttpStatusCode.PartialContent;
var totalLength = stream.Length;
stream = new PartialStream(stream, offset, 10 * 1024 * 1024);


var header = new ContentRangeHeaderValue(offset, offset + stream.Length - 1,totalLength);
response.Headers.Add("Content-Range", header.ToString());
}
response.ContentLength = stream.Length;

return stream;
}

关于c# - 为什么在断点上过早继续会使我的服务器发送无效响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25213260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com