go消息服务器吗,Go语言聊天服务器
本節將帶領大家結合咱們前面所學的知識開發一個聊天的小程序,它可以在幾個用戶之間相互廣播文本消息。這個程序里包含4個goroutine。主goroutine和廣播(broadcaster)goroutine,每一個連接里面有一個連接處理(handleConn)goroutine和一個客戶寫入(clientwriter)goroutine。
廣播器(broadcaster)是關于如何使用select的一個規范說明,因為它需要對三種不同的消息進行響應。
如下所示,主goroutine的工作是監聽端口,接受連接客戶端的網絡連接。對每一個連接,它創建一個新的handleConngoroutine。
packagemainimport("bufio""fmt""log""net")funcmain(){listener,err:=net.Listen("tcp","localhost:8000")iferr!=nil{log.Fatal(err)}gobroadcaster()for{conn,err:=listener.Accept()iferr!=nil{log.Print(err)continue}gohandleConn(conn)}}
下一個是廣播器,它使用局部變量clients來記錄當前連接的客戶集合。每個客戶唯一被記錄的信息是其對外發送消息通道的ID,下面是細節:
typeclientchan
廣播者監聽兩個全局的通道entering和leaving,通過它們通知客戶的到來和離開,如果它從其中一個接收到事件,它將更新clients集合。如果客戶離開,那么它關閉對應客戶對外發送消息的通道。
廣播者也監聽來自messages通道的事件,所有的客戶都將消息發送到這個通道。當廣播者接收到其中一個事件時,它把消息廣播給所有客戶。
現在來看一下每個客戶自己的goroutine。handleConn函數創建一個對外發送消息的新通道,然后通過entering通道通知廣播者新客戶到來。
接著,它讀取客戶發來的每一行文本,通過全局接收消息通道將每一行發送給廣播者,發送時在每條消息前面加上發送者ID作為前綴。一旦從客戶端讀取完畢消息,handleConn通過leaving通道通知客戶離開,然后關閉連接。
funchandleConn(connnet.Conn){ch:=make(chanstring)//對外發送客戶消息的通道goclientWriter(conn,ch)who:=conn.RemoteAddr().String()ch
另外,handleConn函數還為每一個客戶創建了寫入(clientwriter)goroutine,它接收消息,廣播到客戶的發送消息通道中,然后將它們寫到客戶的網絡連接中。客戶寫入者的循環在廣播者收到leaving通知并且關閉客戶的發送消息通道后終止。
下面的信息展示了同一個機器上的一個服務器和兩個客戶端,它們使用netcat程序來聊天:
$gobuildgopl.io/ch8/main
$gobuildgopl.io/ch8/netcat
$./main&
$./netcat
Youare127.0.0.1:64208??$./netcat
127.0.0.1:64211hasarrivedYouare127.0.0.1:64211
Hi!
127.0.0.1:64208:Hi!?127.0.0.1:64208:Hi!
Hiyourself.
127.0.0.1:64211:Hiyourself.?127.0.0.1:64211:Hiyourself.
^C
127.0.0.1:64208hasleft
$./netcat
Youare127.0.0.1:64216?127.0.0.1:64216hasarrived
Welcome.
127.0.0.1:64211:Welcome.127.0.0.1:64211:Welcome.
^C
127.0.0.1:64211hasleft
netcat的完整代碼如下所示:
//netcat.go//netcat是一個簡單的TCP服務器讀/寫客戶端packagemainimport("io""log""net""os")funcmain(){conn,err:=net.Dial("tcp","localhost:8000")iferr!=nil{log.Fatal(err)}done:=make(chanstruct{})gofunc(){io.Copy(os.Stdout,conn)//注意:忽略錯誤log.Println("done")done
當有n個客戶session在連接的時候,程序并發運行著2n+2個相互通信的goroutine,它不需要隱式的加鎖操作。clientsmap限制在廣播器這一個goroutine中被訪問,所以不會并發訪問它。唯一被多個goroutine共享的變量是通道以及net.Conn的實例,它們又都是并發安全的。
總結
以上是生活随笔為你收集整理的go消息服务器吗,Go语言聊天服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让服务器运行js,服务器端JavaS
- 下一篇: 发起一个ajax请求,发送ajax请求