package main import ( "errors" "fmt" "time" ) // 模擬RPC用戶端的請求和接收訊息封裝 func RPCClient(ch chan string, req string) (string, error) { // 向伺服器傳送請求 ch <- req // 等待伺服器返回 select { case ack := <-ch: // 接收到伺服器返回資料 return ack, nil case <-time.After(time.Second): // 超時 return "", errors.New("Time out") } } // 模擬RPC伺服器端接收用戶端請求和回應 func RPCServer(ch chan string) { for { // 接收用戶端請求 data := <-ch // 列印接收到的資料 fmt.Println("server received:", data) // 反饋給用戶端收到 ch <- "roger" } } func main() { // 建立一個無緩衝字串通道 ch := make(chan string) // 並行執行伺服器邏輯 go RPCServer(ch) // 用戶端請求資料和接收資料 recv, err := RPCClient(ch, "hi") if err != nil { // 發生錯誤列印 fmt.Println(err) } else { // 正常接收到資料 fmt.Println("client received", recv) } }
// 模擬RPC用戶端的請求和接收訊息封裝 func RPCClient(ch chan string, req string) (string, error) { // 向伺服器傳送請求 ch <- req // 等待伺服器返回 select { case ack := <-ch: // 接收到伺服器返回資料 return ack, nil case <-time.After(time.Second): // 超時 return "", errors.New("Time out") } }程式碼說明如下:
// 模擬RPC伺服器端接收用戶端請求和回應 func RPCServer(ch chan string) { for { // 接收用戶端請求 data := <-ch // 列印接收到的資料 fmt.Println("server received:", data) //向用戶端反饋已收到 ch <- "roger" } }程式碼說明如下:
// 等待伺服器返回 select { case ack := <-ch: // 接收到伺服器返回資料 return ack, nil case <-time.After(time.Second): // 超時 return "", errors.New("Time out") }程式輸出如下:
server received: hi
client received roger
// 模擬RPC伺服器端接收用戶端請求和回應 func RPCServer(ch chan string) { for { // 接收用戶端請求 data := <-ch // 列印接收到的資料 fmt.Println("server received:", data) // 通過睡眠函數讓程式執行阻塞2秒的任務 time.Sleep(time.Second * 2) // 反饋給用戶端收到 ch <- "roger" } }第 11 行中,time.Sleep() 函數會讓 goroutine 執行暫停 2 秒。使用這種方法模擬伺服器延時,造成用戶端超時。用戶端處理超時 1 秒時通道就會返回:
// 等待伺服器返回 select { case ack := <-ch: // 接收到伺服器返回資料 return ack, nil case <-time.After(time.Second): // 超時 return "", errors.New("Time out") }上面程式碼中,加黑部分的程式碼就會被執行。
func main() { // 建立一個無緩衝字串通道 ch := make(chan string) // 並行執行伺服器邏輯 go RPCServer(ch) // 用戶端請求資料和接收資料 recv, err := RPCClient(ch, "hi") if err != nil { // 發生錯誤列印 fmt.Println(err) } else { // 正常接收到資料 fmt.Println("client received", recv) } }程式碼說明如下: