HTTP处理函数是否能够使用协程和通道?
package main
import (
"fmt"
"log"
"net/http"
"time"
)
var c chan bool = make(chan bool)
//w, 给客户端回复数据
//r, 读取客户端发送的数据
func HandConn(w http.ResponseWriter, r *http.Request) {
fmt.Println("r.Method = ", r.Method) //Method指定HTTP方法(GET、POST、PUT等)。对客户端,""代表GET。
fmt.Println("r.URL = ", r.URL) //URL在服务端表示被请求的URI,在客户端表示要访问的URL。
fmt.Println("r.Header = ", r.Header) //Header字段用来表示HTTP请求的头域。
fmt.Println("r.Body = ", r.Body) //Body是请求的主体。
w.Write([]byte("Hello go ")) //给客户端回复数据
go func() {
for {
log.Println("测试HTTP处理函数是否能够使用协程") // 经过测试是可以使用协程
time.After(3 * time.Second)
}
}()
c <- true // http处理函数不能使用通道
}
func main() {
//注册处理函数, 用户连接, 自动调用指定的处理函数
http.HandleFunc("/", HandConn)
//监听绑定
http.ListenAndServe(":8000", nil)
<-c
}
注意: HTTP 接口处理函数不能使用通道 chanel, 否则出现接口卡死, 无法响应客户端结果;
HTTP 接口处理函数可以使用协程, 不推荐使用, 否则出现不可控的情况, 因为客户端请求一次, 就会开启一个协程;
HTTP 接口处理函数能够使用 defer 语句
package main
import (
"fmt"
"log"
"net/http"
"time"
)
//w, 给客户端回复数据
//r, 读取客户端发送的数据
func HandConn(w http.ResponseWriter, r *http.Request) {
fmt.Println("r.Method = ", r.Method) //Method指定HTTP方法(GET、POST、PUT等)。对客户端,""代表GET。
fmt.Println("r.URL = ", r.URL) //URL在服务端表示被请求的URI,在客户端表示要访问的URL。
fmt.Println("r.Header = ", r.Header) //Header字段用来表示HTTP请求的头域。
fmt.Println("r.Body = ", r.Body) //Body是请求的主体。
// 使用 defer 影响到 http 接口响应客户端的效率(浏览器端需要10s才能响应结果)
defer func() {
time.Sleep(10 * time.Second)
log.Println("测试HTTP处理函数是否能够使用defer语句, 并判断是否影响HTTP接口的性能")
}()
w.Write([]byte("Hello go ")) //给客户端回复数据
}
func main() {
//注册处理函数, 用户连接, 自动调用指定的处理函数
http.HandleFunc("/", HandConn)
//监听绑定
http.ListenAndServe(":8000", nil)
}
编写类似PHP的fastcgi_finish_request()函数效果
package main
import (
"fmt"
"log"
"time"
"net/http"
)
//w, 给客户端回复数据
//r, 读取客户端发送的数据
func HandConn(w http.ResponseWriter, r *http.Request) {
fmt.Println("r.Method = ", r.Method) //Method指定HTTP方法(GET、POST、PUT等)。对客户端,""代表GET。
fmt.Println("r.URL = ", r.URL) //URL在服务端表示被请求的URI,在客户端表示要访问的URL。
fmt.Println("r.Header = ", r.Header) //Header字段用来表示HTTP请求的头域。
fmt.Println("r.Body = ", r.Body) //Body是请求的主体。
response := []byte("Hello go ")
// 设置请求头参数
w.Header().Set("X-Accel-Buffering", "no") // 由上游控制是否缓存上游的响应
w.Header().Set("Connection", "close")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(response))) //字节数, len 计算是切片[]byte("Hello go ") 长度, 实际上是字符串"Hello go "的字节数,
// 添加请求头参数 自定义参数 使用Add()
w.Header().Add("Token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJyZWFkIiwid3JpdGUiLCJzaWduIl19.WE_lw9DW6k_VAGb2YsXHb7CsSXMPoqrOB9zZusV0Nek")
// 写入状态 200
w.WriteHeader(http.StatusOK)
w.Write(response) //给客户端回复数据
if f, ok := w.(http.Flusher); ok {
f.Flush()
// 测试异步执行
time.Sleep(3 * time.Second)
log.Println("异步执行")
}
}
func main() {
//注册处理函数, 用户连接, 自动调用指定的处理函数
http.HandleFunc("/", HandConn)
//监听绑定
http.ListenAndServe(":8000", nil)
}
> # go run main.go
浏览器访问: ip:8000
/*
// 浏览器查看响应头
HTTP/1.1 200 OK
Connection: close
Content-Length: 9
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJyZWFkIiwid3JpdGUiLCJzaWduIl19.WE_lw9DW6k_VAGb2YsXHb7CsSXMPoqrOB9zZusV0Nek
X-Accel-Buffering: no
Date: Thu, 24 Mar 2022 05:35:58 GMT
Content-Type: text/plain; charset=utf-8
*/