如果达到超时,则连接将关闭,并且客户端需要再次发出请求.服务器代码如下所示,假设这些函数根据它们的名称和签名来做明智的事情: import("net/http"时间")func PollingHandler(w http.ResponseWriter,r * http.Request){jobID:= getJobID(r)完成:= 60;完成>0;完成-{//重复〜1分钟状态,错误:= checkStatus(jobID)如果err!= nil {writeError(w,err)返回}如果状态!=无{writeStatus(w,状态)返回}time.Sleep(time.Second)//睡眠1秒}writeNil(w)//特定的响应告诉客户端再次请求.} 处理超时的更好方法是使用上下文包,并使用超时.看起来像这样: import("net/http"时间""golang.org/x/net/context")func PollingHandler(w http.ResponseWriter,r * http.Request){jobID:= getJobID(r)ctx:= context.WithTimeout(context.Background(),time.Second * 60)为了 {选择{情况< -ctx.Done():writeNil(w)默认:状态,错误:= checkStatus(jobID)如果err!= nil {writeError(w,err)返回}如果状态!=无{writeStatus(w,状态)返回}time.Sleep(time.Second)//睡眠1秒}}} 第二个版本将在更可靠的时间内返回,尤其是在 checkStatus 调用速度较慢的情况下.I know that HTTP is a request-response protocol. My problem, in short, is that a client makes a request to the server to start a long running-process, and I want to inform the client of the progress with a simple JSON message containing progress info.In HTTP/1.1 I know that I could use a WebSocket or server-sent events (SSE) or long polling.Now I know that HTTP/2 does not support WebSocket yet.My question is, what is the optimal way to handle such things over HTTP/2?Are there any new things that I am not aware of to handle server-initiated requests in HTTP/2?I am using the Go language, if that matters. 解决方案 Before websockets we had polling. This literally means having the client periodically (every few seconds, or whatever time period makes sense for your application), make a request to the server to find out the status of the job.An optimization many people use is "long" polling. This involves having the server accept the request, and internally to the server, check for changes, and sleep while there are none, until either a specific timeout is reached or the desired event occurs, which is then messaged back to the client.If a timeout is reached, the connection is closed and the client needs to make another request. The server code would look something like the following, assume the functions do sensible things based on their names and signatures:import ( "net/http" "time")func PollingHandler(w http.ResponseWriter, r *http.Request) { jobID := getJobID(r) for finish := 60; finish > 0; finish-- { // iterate for ~1 minute status, err := checkStatus(jobID) if err != nil { writeError(w, err) return } if status != nil { writeStatus(w, status) return } time.Sleep(time.Second) // sleep 1 second } writeNil(w) // specific response telling client to request again.}A better way to handle the timeout would be to use the context package and create a context with a timeout. That would look something like:import ( "net/http" "time" "golang.org/x/net/context")func PollingHandler(w http.ResponseWriter, r *http.Request) { jobID := getJobID(r) ctx := context.WithTimeout(context.Background(), time.Second * 60) for { select{ case <-ctx.Done(): writeNil(w) default: status, err := checkStatus(jobID) if err != nil { writeError(w, err) return } if status != nil { writeStatus(w, status) return } time.Sleep(time.Second) // sleep 1 second } }}This second version is just going to return in a more reliable amount of time, especially in the case where checkStatus may be a slower call. 这篇关于服务器启动的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-27 07:27
查看更多