demo
我们知道,Kubernetes中ListWatch机制,组件可以先使用List获取全量的对象,然后再通过Watch建立与Apiserver的长连接,获取对象的变化,并进行相应的处理。并次demo就展示Go语言如何建立长连接,及以json对象为例,说明服务端如何发送数据,client端如何接收数据。
server端代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package main import ( "fmt" "net/http" "time" "encoding/json" ) type Person struct { Name string Age int } func SayHello(w http.ResponseWriter, req *http.Request) { p := Person{"Mike", 20} enc := json.NewEncoder(w) if err := enc.Encode(p); err != nil { fmt.Println("error") } if f, ok := w.(http.Flusher); ok { f.Flush() } else { fmt.Println("no flush") } time.Sleep(5*time.Second) if err := enc.Encode(p); err != nil { fmt.Println("error") } } func main() { http.HandleFunc("/hello", SayHello) http.ListenAndServe(":8001", nil) }
|
server端代码会把127.0.0.1:8001/hello的请求使用SayHello()函数进行处理。SayHello()向数据连接先发送一个json串,然后过5秒后,再发送一个json串。向数据流中发送数据由json包的Encoder完成。
client端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main import ( "fmt" "net/http" "encoding/json" ) func main() { client := &http.Client{} url := "http://127.0.0.1:8001/hello" request, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } request.Header.Set("Connection", "close") response, _ := client.Do(request) dec := json.NewDecoder(response.Body) for { var v map[string]interface{} if err := dec.Decode(&v); err != nil { fmt.Println(err) break } fmt.Println(v) } response.Body.Close() }
|
client端代码使用http执行请求,并使用json的Decoder自动从数据流中解析出一个json对象,最后关闭连接。
1 2 3
| map[Name:Mike Age:20] map[Name:Mike Age:20] EOF
|
当请求server端时,client先打印出map[Name:Mike Age:20]
,过5秒,再打印出第二行map[Name:Mike Age:20]
。这就是watcher的原型。