GO使用socket和channel實現(xiàn)簡單控制臺聊天室
使用socket和channel,實現(xiàn)簡單控制臺聊天室
這里使用socket和channel,演示在GO中如何編寫一個簡單網絡程序
功能分析
聊天室主要功能:用戶可以加入/離開聊天室;每個用戶發(fā)送的消息,廣播給所有人
聊天室分為客戶端和服務端,客戶端負責發(fā)送消息和打印服務器消息,服務器負責接收客戶端消息,并廣播給所有人
客戶端可以使用telnet程序
服務端是需要實現(xiàn)的。需要實現(xiàn)的功能,
- 如何保存多個客戶端的連接,管理連接的接入與斷開
- 如何接收和廣播客戶端消息
實現(xiàn)思路
通過功能分析,拆分為聊天室結構體和客戶端結構體
聊天室結構體負責管理當前接入的客戶端和廣播消息
客戶端結構體負責管理socket連接和需要接收與發(fā)送的數(shù)據
客戶端連接/斷開時通知聊天室;客戶端發(fā)送的消息實際是轉發(fā)給聊天室,然后聊天室再廣播出去
完整代碼
package main import ( "bufio" "fmt" "log" "net" ) type Client struct { id string conn *net.Conn message chan string } type Hub struct { clients map[*Client]bool entering chan *Client leaving chan *Client messages chan string } func main() { hub := &Hub{ clients: make(map[*Client]bool), entering: make(chan *Client), leaving: make(chan *Client), messages: make(chan string), } listener, err := net.Listen("tcp", ":8000") if err != nil { log.Fatal(err) } go hub.broadcaster() for { conn, err := listener.Accept() if err != nil { log.Println(err) continue } go hub.handleConn(conn) } } func (hub *Hub) broadcaster() { for { select { case msg := <-hub.messages: for cli := range hub.clients { cli.message <- msg } case cli := <-hub.entering: hub.clients[cli] = true case cli := <-hub.leaving: delete(hub.clients, cli) } } } func (hub *Hub) handleConn(conn net.Conn) { defer conn.Close() ch := make(chan string) who := conn.RemoteAddr().String() client := &Client{who, &conn, ch} go hub.writeLoop(client) ch <- "welcome " + client.id hub.messages <- client.id + " join chat" hub.entering <- client hub.readLoop(client) hub.messages <- client.id + " has left" hub.leaving <- client } func (hub *Hub) writeLoop(client *Client) { for msg := range client.message { fmt.Fprintf(*client.conn, "%s\n", msg) } } func (hub *Hub) readLoop(client *Client) { input := bufio.NewScanner(*client.conn) for input.Scan() { hub.messages <- client.id + ": " + input.Text() } }
分析
實現(xiàn)的關鍵是封裝了客戶端通信channel,無論是遠程發(fā)送過來的消息還是聊天室廣播的消息,都通過這個channel傳遞,且這個channel是綁定客戶端的
參考鏈接中,直接使用channel來定義客戶端type client chan<- string
,其實更能表達這一點
為了容易理解,這里將channel封裝為客戶端的一個通信管道,客戶端還可以有別的屬性,例如:id、連接和超時時間等
參考: Go 網絡編程示例
到此這篇關于GO實現(xiàn)簡單控制臺聊天室的文章就介紹到這了,更多相關go控制臺聊天室內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于golang uint8、int8與byte的區(qū)別說明
這篇文章主要介紹了基于golang uint8、int8與byte的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03windows下使用vscode搭建golang環(huán)境并調試的過程
這篇文章主要介紹了在windows下使用vscode搭建golang環(huán)境并進行調試,主要包括安裝方法及環(huán)境變量配置技巧,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09wind10 idea中 go 開發(fā)環(huán)境搭建教程圖解
這篇文章主要介紹了wind10 idea中 go 開發(fā)環(huán)境搭建過程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06Golang自定義開發(fā)Prometheus?exporter詳解
Exporter是基于Prometheus實施的監(jiān)控系統(tǒng)中重要的組成部分,承擔數(shù)據指標的采集工作,這篇文章主要為大家介紹了如何自定義編寫開發(fā)?Prometheus?exporter,感興趣的可以了解一下2023-06-06