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的原型。