代码之家  ›  专栏  ›  技术社区  ›  RichyDavisWindow3

Goroutine已经从请求开始了GO Web服务器,但是客户端断开连接,Web服务器是否可以关闭那个特定的GOODUTIN?

  •  0
  • RichyDavisWindow3  · 技术社区  · 6 年前

    每当一个web请求从客户端传入时,它都会生成一个goroutine来处理每个请求。如果客户机恰好断开与连接的连接,Web服务器是否可以关闭该特定的goroutine,或者该goroutine是否会在执行完所有代码后发现客户机已断开连接?

    2 回复  |  直到 6 年前
        1
  •  4
  •   syllabix    6 年前

    除了从调用处理程序返回读或写错误之外,执行GO例程将不会自动处理清理较长时间运行的操作,但GO提供了处理此问题的好方法。

    首先,如果你不熟悉 context package -这是一种功能强大且惯用的同步go例程和取消行为的方法,我强烈建议您阅读博客 Go Concurrency Patterns: Context 是的。

    大致如下:

    func MyServiceFunc(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                break
            default:
                //do work
            }
        }
    }
    
    func MyRequestHandler(res http.ResponseWriter, req *http.Request) {
        MyServiceFunc(req.Context())       
       //write response...
    }
    

    或者你可以用 CloseNotifier 接口A http.ResponseWriter 此外,还可以执行类似于以下简单示例的操作:

    func MyServiceFunc(notifier <-chan bool) {
        for {
            select {
            case <-notifier:
                break
            default:
                //do work
            }
        }
    }
    
    
    func MyRequestHandler(res http.ResponseWriter, req *http.Request) {
        notifier := res.(http.CloseNotifier).CloseNotify()
        MyServiceFunc(notifier)
        //write response...
    }
    

    或者,结合使用两种方法的简单示例:

    func MyRequestHandler(res http.ResponseWriter, req *http.Request) {
    
        notifier := res.(http.CloseNotifier).CloseNotify()
        ctx, cancel := context.WithCancel(req.Context())
    
        go func(closer <-chan bool) {
            <-closer //the notifer blocks until the send
            cancel() //explicitly cancel all go routines
        }(notifier)
    
        go MyServiceFunc(ctx)
        MyOtherServiceFunc(ctx)
        //write response...
    }
    
        2
  •  1
  •   Cerise Limón    6 年前

    如果读取或写入连接时出错,或者请求或响应头指示应关闭连接,则从处理程序返回时每个连接goroutine将退出。

    处理程序可以使用 Context 从返回 Request.Context() 是的。