【问题标题】:Read response from WebResponse Response Stream从 WebResponse 响应流中读取响应
【发布时间】:2013-07-31 03:58:50
【问题描述】:

我一直在 F# 交互式会话中尝试一些基本的 HTTP 请求响应操作,以尝试更好地了解该语言。这里的一切似乎都按预期工作,除了当我得到我的 HTTP 请求的响应流时,我似乎永远无法从中读取任何内容。在下面的代码中,我每次都从 printfn 行获取文本,但 responseString 的值似乎总是为空。我错过了什么明显的东西吗?

let httpListener = new HttpListener()
httpListener.Prefixes.Add("http://*:8020/")

let getContext = Async.FromBeginEnd(httpListener.BeginGetContext, httpListener.EndGetContext)

let processRequest = async {
    while true do
        let! context = getContext
        let request = context.Request
        use requestReader = new StreamReader(request.InputStream)
        let requestString = requestReader.ReadToEnd()
        let response = context.Response
        use streamWriter = new StreamWriter(response.OutputStream)
        streamWriter.WriteLine "A response!"
        response.Close()
}

httpListener.Start()

let maxThreads = 10
for n = 0 to maxThreads do
    Async.Start processRequest

printfn "HttpListener started with %d maximum threads processing requests." maxThreads

let sendRequest = async {
    let request = WebRequest.Create("http://localhost:8020") :?> HttpWebRequest
    let postBytes = Encoding.ASCII.GetBytes("Issuing HTTP")
    request.Method <- "POST"
    request.ContentType <- "application/x-www-form-urlencoded"
    request.ContentLength <- int64 postBytes.Length
    let requestStream = request.GetRequestStream()
    requestStream.Write(postBytes, 0, postBytes.Length)
    requestStream.Close()

    let! response = Async.FromBeginEnd(request.BeginGetResponse, request.EndGetResponse)
    let responseStream = response.GetResponseStream()
    use streamReader = new StreamReader(responseStream)
    let responseString = streamReader.ReadToEnd()

    printfn "Received the following response: %s" responseString
}

for n = 0 to maxThreads do
    Async.Start sendRequest

【问题讨论】:

    标签: http f# stream


    【解决方案1】:

    您需要减少 StreamWriter 的使用范围,以便在 Dispose 上刷新它。

    let processRequest = async {
        while true do
            let! context = getContext
            let request = context.Request
            use requestReader = new StreamReader(request.InputStream)
            let requestString = requestReader.ReadToEnd()
            let response = context.Response
            do
                use streamWriter = new StreamWriter(response.OutputStream)
                streamWriter.WriteLine "A response!"
            response.Close()
    }
    

    【讨论】:

    • 太棒了,谢谢!为了清楚起见,您是在谈论消耗 using 块时发生的处置吗?还是在 response.Close() 上?我习惯于在 C# 中使用 {} 来限定块,因此能够在一行上定义一个块的想法让我感到困惑。为什么我能够从 InputStream 中获取 requestString 而无需以与您展示的方式相同的方式对其进行限定?
    • use 绑定在一行上声明,但在包含块结束之前一直在范围内,在您的情况下是 processRequest 函数,或者在此答案的情况下是 do 块。您也可以使用括号和using 来缩小范围。
    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多