我想的事為每個client fd開兩個goroutine,一個recv,一個send。同時還有加2個channel,一個用於recv routine向邏輯主執行緒傳送收到的資料,一個用於邏輯主執行緒向send goroutine傳送待發送的資料,是這樣的麼?
實際上需要 3 個 goroutine,一個 read,一個 send,還有一個 handle。
read goroutine 讀,然後寫入 recevice chan。
write goroutine 把 send chan 的東西寫。
handle goroutine 是 conn 的主要處理邏輯,負責把 recevice chan 的東西讀出來 call 業務邏輯。
業務邏輯中要寫資料就直接寫入 send chan。
這樣就可以保證,業務邏輯的讀寫都是在 handle goroutine 上處理,而避免 race 產生。
如果需要定時任務(比如心跳),就在 handle goroutine 上加上一個 timer.C;
如果需要 goroutine 下發任務,在 handle goroutine 增加一個 task chan,hanlde 收到 task 後處理業務;
如果需要輸出結果,那就增加 result chan,業務邏輯把資料輸出即可。
----------------------------
還有,如果我開2個goroutine的話,client斷開連線了,假設recv goroutine先發生err並且close(fd),那在send goroutine中該如何處理呢?有可能不應該這樣處理,那應該怎麼處理呢?
如果 net.Conn Close() 了,不論 Read() 阻塞還是 Write() 阻塞都會立即收到 err 返回。
一般來說,Write() 是不可能主動知道連線斷開的,除非是 SetDeadline() 猜測對方斷掉了,指定時間內沒有寫成功就認為是斷開。Read() 是可以主動收到對方發來的斷開(TCP FIN),但也沒辦法知道異常的斷開(當然也可以設定超時)。
無論是誰,是確實收到 FIN 還是 Deadline 猜測斷開,只要 Close() 大家就知道連線斷開了。
handle goroutine 還有一個用處就是:你的程式主動結束的時候,能正確的 close conn,讓對方知道你是真的斷開了,而不用去猜。
我想的事為每個client fd開兩個goroutine,一個recv,一個send。同時還有加2個channel,一個用於recv routine向邏輯主執行緒傳送收到的資料,一個用於邏輯主執行緒向send goroutine傳送待發送的資料,是這樣的麼?
實際上需要 3 個 goroutine,一個 read,一個 send,還有一個 handle。
read goroutine 讀,然後寫入 recevice chan。
write goroutine 把 send chan 的東西寫。
handle goroutine 是 conn 的主要處理邏輯,負責把 recevice chan 的東西讀出來 call 業務邏輯。
業務邏輯中要寫資料就直接寫入 send chan。
這樣就可以保證,業務邏輯的讀寫都是在 handle goroutine 上處理,而避免 race 產生。
如果需要定時任務(比如心跳),就在 handle goroutine 上加上一個 timer.C;
如果需要 goroutine 下發任務,在 handle goroutine 增加一個 task chan,hanlde 收到 task 後處理業務;
如果需要輸出結果,那就增加 result chan,業務邏輯把資料輸出即可。
----------------------------
還有,如果我開2個goroutine的話,client斷開連線了,假設recv goroutine先發生err並且close(fd),那在send goroutine中該如何處理呢?有可能不應該這樣處理,那應該怎麼處理呢?
如果 net.Conn Close() 了,不論 Read() 阻塞還是 Write() 阻塞都會立即收到 err 返回。
一般來說,Write() 是不可能主動知道連線斷開的,除非是 SetDeadline() 猜測對方斷掉了,指定時間內沒有寫成功就認為是斷開。Read() 是可以主動收到對方發來的斷開(TCP FIN),但也沒辦法知道異常的斷開(當然也可以設定超時)。
無論是誰,是確實收到 FIN 還是 Deadline 猜測斷開,只要 Close() 大家就知道連線斷開了。
handle goroutine 還有一個用處就是:你的程式主動結束的時候,能正確的 close conn,讓對方知道你是真的斷開了,而不用去猜。