最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言實現(xiàn)一個簡單的并發(fā)聊天室的項目實戰(zhàn)

 更新時間:2022年03月18日 16:06:24   作者:Sirius_7  
本文主要介紹了Go語言實現(xiàn)一個簡單的并發(fā)聊天室的項目實戰(zhàn),文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下

寫在前面

Go語言在很多方面天然的具備很多便捷性,譬如網(wǎng)絡編程,并發(fā)編程。而通道則又是Go語言實現(xiàn)并發(fā)編程的重要工具,因為其承擔著通道之間互相通信的重任。并且因為其本身就是并發(fā)安全的,所以在某些場景下是非常好用的。

并發(fā)聊天服務器

這里主要是實現(xiàn)一個簡單的并發(fā)聊天服務器。首先,客戶端可以在服務器中注冊自己的信息(登錄以及退出),客戶端發(fā)出的所有的信息由服務器向各個客戶端進行轉發(fā),或者換句話說是廣播。

具體代碼

服務端

說的再多,沒有代碼簡單明了,直接上代碼~

package main

import (
?? ?"bufio"
?? ?"fmt"
?? ?"log"
?? ?"net"
)
type client chan <- string //定義一個單向的向外發(fā)送數(shù)據(jù)的通道

var (
?? ?entering = make(chan client)
?? ?leaving = make(chan client)
?? ?messages = make(chan string)
)

func main() {
?? ?listener, err := net.Listen("tcp","localhost:8000")
?? ?if err != nil {
?? ??? ?log.Fatal("network is broken", err)
?? ?}
?? ?go broadcaster()
?? ?for {
?? ??? ?conn, err := listener.Accept()
?? ??? ?if err != nil {
?? ??? ??? ?log.Print(err)
?? ??? ??? ?continue
?? ??? ?}
?? ??? ?go handleConn1(conn)
?? ?}
}
func broadcaster() ?{
?? ?clients := make(map[client]bool) //存儲每個client的登錄狀態(tài)
?? ?for{
?? ??? ?select {
?? ??? ?case msg := <-messages:
?? ??? ??? ?for cli := range clients {
?? ??? ??? ??? ?cli <- msg
?? ??? ??? ?}
?? ??? ?case cli := <-entering:
?? ??? ??? ?clients[cli] = true
?? ??? ?case cli := <-leaving:
?? ??? ??? ?delete(clients,cli)
?? ??? ??? ?close(cli)
?? ??? ?}
?? ?}
}

func handleConn1(conn net.Conn) ?{
?? ?ch := make(chan string)
?? ?go clientWriter(conn, ch)
?? ?who := conn.RemoteAddr().String()
?? ?ch <- "You are " + who
?? ?entering <- ch
?? ?messages <- who + "has arrived"

?? ?input := bufio.NewScanner(conn)
?? ?for input.Scan() {
?? ??? ?messages <- who + ":" + input.Text()
?? ?}

?? ?leaving <- ch
?? ?messages <- who + "has left"
?? ?conn.Close()
}

func clientWriter(conn net.Conn, ch <- chan string) ?{
?? ?for msg := range ch {
?? ??? ?fmt.Fprintln(conn, msg)
?? ?}
}

客戶端

客戶端相對簡單,只是涉及到信息的發(fā)送和接受工作。

package main

import (
?? ?"io"
?? ?"log"
?? ?"net"
?? ?"os"
)

func main() {
?? ?conn, err := net.Dial("tcp","localhost:8000")
?? ?if err != nil {
?? ??? ?log.Fatal("Connected has been refused!",err)
?? ?}
?? ?defer conn.Close()
?? ?go mesCopy(os.Stdout,conn)
?? ?mesCopy(conn,os.Stdin)
}

func mesCopy(des io.Writer, res io.Reader) ?{
?? ?if _, err := io.Copy(des, res); err != nil {
?? ??? ?log.Print("wrong!")
?? ?}
}

 總結

實現(xiàn)原理較為簡單,所以代碼并沒有多少注釋,如果有任何疑問,歡迎留言討論。最后說一句,在MIT的課程中,其實并不是很推薦在并發(fā)編程中使用通道chan,除非你對其應用的場景和可能出現(xiàn)的情況有很好的把握,不然可能會出現(xiàn)很多不可預測的事情,譬如死鎖(見另外一篇博客)。在這種時候,共享變量將會是一種很好的選擇,具體查看go多線程實踐。

到此這篇關于Go語言實現(xiàn)一個簡單的并發(fā)聊天室的項目實戰(zhàn)的文章就介紹到這了,更多相關Go語言 并發(fā)聊天室內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解如何在Go中實現(xiàn)優(yōu)雅停止

    詳解如何在Go中實現(xiàn)優(yōu)雅停止

    和其他語言相比,Go 中有相同也有不同,相同的是實現(xiàn)思路上和其他語言沒啥差異,不同在于 Go 采用的是 goroutine + channel 的并發(fā)模型,與傳統(tǒng)的進程線程相比,實現(xiàn)細節(jié)上存在差異,本文將從實際場景和它的一般實現(xiàn)方式展開,逐步討論這個話題,需要的朋友可以參考下
    2024-04-04
  • Go中的new()和make()函數(shù)區(qū)別及底層原理詳解

    Go中的new()和make()函數(shù)區(qū)別及底層原理詳解

    這篇文章主要為大家介紹了Go中的new()和make()函數(shù)區(qū)別及底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 一文詳解Golang中consul的基本使用

    一文詳解Golang中consul的基本使用

    consul是一個開源服務注冊和服務發(fā)現(xiàn)的中心,可以用于微服務的注冊和服務之間的調用的發(fā)現(xiàn),幫助上游服務找到下游服務的具體ip:port或者是domain,也可以使用dns的方式讓consul幫你去做轉發(fā)。本文就來講講它的具體使用吧
    2023-03-03
  • Golang Socket Server自定義協(xié)議的簡單實現(xiàn)方案

    Golang Socket Server自定義協(xié)議的簡單實現(xiàn)方案

    這篇文章主要介紹了Golang Socket Server自定義協(xié)議的簡單實現(xiàn)方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言JSON編解碼神器之marshal的運用

    Go語言JSON編解碼神器之marshal的運用

    這篇文章主要為大家詳細介紹了Go語言中JSON編解碼神器——marshal的運用,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-09-09
  • go micro集成鏈路跟蹤的方法和中間件原理解析

    go micro集成鏈路跟蹤的方法和中間件原理解析

    這篇文章主要介紹了go-micro集成鏈路跟蹤的方法和中間件原理,關于Http或者說是Restful服務的鏈路跟蹤,go-micro的httpClient支持CallWrapper,可以用WrapCall來添加鏈路跟蹤的CallWrapper,本文給大家介紹的非常詳細,需要的朋友參考下吧
    2022-05-05
  • Golang中map數(shù)據(jù)類型的使用方法

    Golang中map數(shù)據(jù)類型的使用方法

    這篇文章主要介紹了Golang中map數(shù)據(jù)類型的使用方法,文章圍繞主題展開詳細的內容戒殺,具有一定的參考價值,需要的朋友可以參考一下
    2022-09-09
  • Golang 如何判斷數(shù)組某個元素是否存在 (isset)

    Golang 如何判斷數(shù)組某個元素是否存在 (isset)

    這篇文章主要介紹了Golang 如何判斷數(shù)組某個元素是否存在 (isset),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • go語言的四數(shù)相加等于指定數(shù)算法

    go語言的四數(shù)相加等于指定數(shù)算法

    這篇文章主要介紹了go語言的四數(shù)相加等于指定數(shù)算法的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Golang實現(xiàn)基于Redis的可靠延遲隊列

    Golang實現(xiàn)基于Redis的可靠延遲隊列

    redisson?delayqueue可以使用redis的有序集合結構實現(xiàn)延時隊列,遺憾的是go語言社區(qū)中并無類似的庫。不過問題不大,本文將用Go語言實現(xiàn)這一功能,需要的可以參考一下
    2022-06-06

最新評論

镇远县| 额尔古纳市| 特克斯县| 屏南县| 南宫市| 来安县| 信丰县| 沿河| 大名县| 将乐县| 施秉县| 台南市| 城市| 西昌市| 三原县| 侯马市| 双辽市| 盐边县| 沙坪坝区| 从江县| 雷波县| 方正县| 丹凤县| 义马市| 长顺县| 乌鲁木齐县| 萨迦县| 太湖县| 鄂托克前旗| 黔南| 永顺县| 德阳市| 西昌市| 仙居县| 黎平县| 苏尼特左旗| 永兴县| 淮安市| 大余县| 宣恩县| 喀喇|