流式传输HTTP客户端很长时间直到第一个响应字节

时间:2018-04-13 13:50:29

标签: http go

我正在尝试编写一个Go HTTP客户端,用于从HTTP服务器传输事件数据。我的问题是响应的第一个字节可能需要几个小时才能得到它,这包括响应头。甚至可能我从未得到回应。

我目前使用此客户端获取net/http: request canceled (Client.Timeout exceeded while awaiting headers)

Client = &http.Client{
    Transport: &http.Transport{
        Dial: (&net.Dialer{                                                                         
            Timeout:   0,
            KeepAlive: 30 * time.Second,
        }).Dial,
        Proxy: http.ProxyURL(proxyUrl),
        ResponseHeaderTimeout: 0,
    },
    Timeout: 0,
}

为了使我的连接不超时,我想不到任何超时设置为零。我错过了什么?

我正在使用go version go1.8 linux/amd64

编辑1: 我无法更改我正在编写客户端的服务器。

2 个答案:

答案 0 :(得分:0)

超时设置不适用于此问题,您需要重新设计应用程序。

也许您可以在服务器端执行以下操作:

  1. 获取请求参数
  2. 将它们转换为缓存键(文件名,内存缓存,数据库键 - 无论你喜欢什么),例如通过对参数进行排序并使用SHA-1 / -256 / 512对它们进行散列
  3. 检查此缓存密钥当前是否正在处理(例如锁存在) - 返回类似“稍后再试”的内容(如果为true)
  4. 将长时间运行的工作推送到后台进程(可能使用Gearman?)并返回“稍后再试”
  5. 在后台:

    1. 为缓存密钥创建锁定,包括合理的超时
    2. 创建数据(运行数小时的部分)
    3. 将结果写入缓存
    4. 您的客户可以轻松发送请求,并立即获得结果。结果可能是“稍后再试”或缓存的结果。如果收到“稍后再试”消息,客户端应该休眠一段时间,然后重试该请求。

答案 1 :(得分:0)

我发现在默认的http客户端中,我设置为零的超时已经为零。所以从我自己的客户端删除

func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        if collectionView == 1configcollectionview {
            let itemToMove = keystring[sourceIndexPath.row]
            keystring.remove(at: sourceIndexPath.row)
            keystring.insert(itemToMove, at: destinationIndexPath.row)
            print("Starting Index: \(sourceIndexPath.row)")
            print("Ending Index: \(destinationIndexPath.row)")
            UserDefaults.standard.set(keystring, forKey:"keystringreorder")
            //  let movekey = keystring.remove(at: sourceIndexPath.item)
            //  keystring.insert(movekey, at: destinationIndexPath.item)
        }
        if collectionView == 2configcollectionview {
            let movekey1 = keystring1.remove(at: sourceIndexPath.item)
            keystring1.insert(movekey1, at: destinationIndexPath.item)
            print("Starting Index: \(sourceIndexPath.item)")
            print("Ending Index: \(destinationIndexPath.item)")
            UserDefaults.standard.set(keystring1, forKey:"keystringreorder1")

        }
        if collectionView == 3configcollectionview {
            let movekey2 = keystring2.remove(at: sourceIndexPath.item)
            keystring2.insert(movekey2, at: destinationIndexPath.item)
            print("Starting Index: \(sourceIndexPath.item)")
            print("Ending Index: \(destinationIndexPath.item)")
            UserDefaults.standard.set(keystring2, forKey:"keystringreorder2")


        }


    }

 override func viewDidLoad() {
        super.viewDidLoad()
    let orderkeystring = UserDefaults.standard.object(forKey:"keystringreorder")
        if(orderkeystring != nil) {
            keystring = orderkeystring as! [String]
        }
    }

Client = &http.Client{ Transport: &http.Transport{ Dial: (&net.Dialer{ KeepAlive: 30 * time.Second, }).Dial, Proxy: http.ProxyURL(proxyUrl), }, } 中的保持活动选项似乎与它无关。这留下了代理。

在代理实现中,我找到了一个超时的客户端:

Dial

删除超时解决了我的问题。