真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

golang聊天室學(xué)習(xí)筆記

1聊天室服務(wù)器

專注于為中小企業(yè)提供做網(wǎng)站、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)南昌免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

package?main

import?(
????"fmt"
????"net"
????"strings"
????"time"
)

//定義的此結(jié)構(gòu)體為全局map的value值,包括每一個(gè)用戶的姓名,ip地址和私人管道
type?client?struct?{
????name?string
????addr?string
????C????chan?string
}

/*這個(gè)函數(shù)是將私人管道中的內(nèi)容發(fā)送給用戶,配合全局管道Message使用可以實(shí)現(xiàn)廣播的功能,
單獨(dú)使用可以實(shí)現(xiàn)私聊的功能*/
func?writemsg2client(clinet?client,?conn?net.Conn)?{
????for?m?:=?range?clinet.C?{
????????conn.Write([]byte(m?+?"\n"))
????}
}

//這只是一個(gè)封裝好用來(lái)統(tǒng)一(發(fā)送信息格式)的小函數(shù),不用在意
func?makemsg(name?string,?addr?string,?s?string)?string?{
????return?"["?+?addr?+?"]"?+?name?+?":"?+?s
}

//每一個(gè)進(jìn)入聊天室的用戶都將啟動(dòng)一個(gè)handleconn的go程來(lái)處理事件
func?handleconn(conn?net.Conn)?{
????defer?conn.Close()
????/*用戶連接進(jìn)來(lái)以后要初始化全局map,把自己的信息加入到字典里,相當(dāng)于進(jìn)到聊天室里之前要登
??????記一下個(gè)人信息,注意姓名初始為ip地址。*/
????addr?:=?conn.RemoteAddr().String()
????fmt.Printf("用戶%s進(jìn)入了房間\n",?addr)
????client?:=?client{addr,?addr,?make(chan?string)}
????//在這里啟動(dòng)子go程,功能上面已經(jīng)提及,具體就是會(huì)寫信息給自己連接的客戶端
????go?writemsg2client(client,?conn)
????onlinemap[addr]?=?client
????//登錄進(jìn)來(lái)一切準(zhǔn)備就緒后就給所有人廣播上線信息啦
????Message?<-?makemsg(client.name,?addr,?"login")
????//下面這三個(gè)變量服務(wù)于下面一些小功能
????var?haschat?=?make(chan?bool)
????var?ifquit?=?make(chan?bool)
????var?flag?bool
????//從這單獨(dú)開啟一個(gè)go程來(lái)讀取用戶輸入的信息
????go?func()?{
????????buf?:=?make([]byte,?4096)
????????for?{
????????????n,?_?:=?conn.Read(buf)
????????????if?n?==?0?{
????????????????fmt.Printf("%s離開了房間\n",?client.name)
????????????????ifquit?<-?true
????????????????return
????????????}
????????????//改名功能的實(shí)現(xiàn)
????????????if?string(buf[:7])?==?"Rename|"?{
????????????????client.name?=?strings.Split(string(buf[:n]),?"|")[1]
????????????????onlinemap[addr]?=?client
????????????????conn.Write([]byte("rename?success\n"))
????????????}?else?if?string(buf[:n-1])?==?"/who"?{
????????????????//查詢?cè)诰€用戶信息的功能
????????????????for?_,?s?:=?range?onlinemap?{
????????????????????conn.Write([]byte(s.name?+?"online\n"))
????????????????}
????????????}?else?if?string(buf[:2])?==?"m|"?&&?strings.Count(string(buf[:n]),?"|")?==?2?{
????????????????/*私聊功能的實(shí)現(xiàn),其實(shí)私聊功能就是跳過(guò)了往全局Message里傳輸信息,
??????????????????改為直接向私人管道里傳輸信息*/
????????????????flag?=?true
????????????????slice?:=?strings.Split(string(buf[:n]),?"|")
????????????????fmt.Println(slice[1])
????????????????for?_,?a?:=?range?onlinemap?{
????????????????????//遍歷所有在線用戶,向指定的用戶管道中發(fā)送信息
????????????????????if?a.name?==?slice[1]?{
????????????????????????flag?=?false
????????????????????????a.C?<-?makemsg(client.name,?addr,?slice[2])
????????????????????????conn.Write([]byte("send?success"))

????????????????????}
????????????????}
????????????????if?flag?{
????????????????????conn.Write([]byte("no?such?man?or?not?online"))
????????????????}
????????????}?else?{
????????????????Message?<-?makemsg(client.name,?addr,?string(buf[:n]))
????????????}
????????????haschat?<-?true
????????}
????}()
????for?{
????????select?{
????????case?<-haschat:
????????//超時(shí)強(qiáng)踢
????????case?<-time.After(time.Minute?*?100):
????????????delete(onlinemap,?addr)
????????????Message?<-?makemsg(client.name,?addr,?"out?time?to?leave")
????????????close(client.C)
????????????return
????????case?<-ifquit:
????????????//退出處理
????????????delete(onlinemap,?addr)
????????????Message?<-?makemsg(client.name,?addr,?"out?time?to?leave")
????????????close(client.C)
????????????return
????????}
????}
}

//這個(gè)函數(shù)用來(lái)將全局Message中的內(nèi)容全部塞到私人管道C里,實(shí)現(xiàn)上下線廣播和群聊的功能
func?Manager()?{
????for?{
????????msg?:=?<-Message
????????for?_,?s?:=?range?onlinemap?{
????????????s.C?<-?msg
????????}
????}
}

var?Message?=?make(chan?string)
var?onlinemap?map[string]client?=?make(map[string]client)

//主函數(shù)
func?main()?{
????listener,?_?:=?net.Listen("tcp",?"127.0.0.1:9876")
????defer?listener.Close()
????//提前開啟全局Message的go程,防止被阻塞
????go?Manager()
????for?{
????????conn,?err?:=?listener.Accept()
????????if?err?!=?nil?{
????????????fmt.Println("accept?err",?err)
????????????continue
????????}
????????//每一個(gè)連接進(jìn)來(lái)的用戶都會(huì)被分配進(jìn)入一個(gè)子go程,用來(lái)處理上面我們提到的各種功能
????????go?handleconn(conn)
????}
}

/*備注
1、??listener,?_?:=?net.Listen("tcp",?"127.0.0.1:9876")
監(jiān)聽(tīng)啟動(dòng)

2、??go?Manager()開啟全局Message的go程,防止被阻塞,沒(méi)有消息便被阻塞,有消息便會(huì)被喚起,
消息發(fā)送完畢后重新等待消息,有消息變發(fā)送沒(méi)消息便阻塞等待(Message?是一個(gè)字符串channel?)。

接收到消息后,遍歷所有在線人員,并把消息發(fā)送給client的私人通道。

func?Manager()?{
????for?{
????????msg?:=?<-Message
????????for?_,?s?:=?range?onlinemap?{
????????????s.C?<-?msg
????????}
????}
}

3、私人通道消息處理
這個(gè)函數(shù)是將私人管道中的內(nèi)容發(fā)送給用戶,配合全局管道Message使用可以實(shí)現(xiàn)廣播的功能。
單獨(dú)使用可以實(shí)現(xiàn)私聊的功能(m|客戶端連接ip加端口|發(fā)送消息)(m|127.0.0.1:59700|hello)。
這個(gè)函數(shù)也是等待消息,收到消息后被喚醒執(zhí)行,消息執(zhí)行完畢后等待新消息,沒(méi)有阻塞,有就處理
func?writemsg2client(clinet?client,?conn?net.Conn)?{
????for?m?:=?range?clinet.C?{
????????conn.Write([]byte(m?+?"\n"))
????}
}


*/

2、聊天室客戶端

package?main

import?(
????"bufio"
????"fmt"
????"net"
????"os"
????"strings"
)

func?readFromServer(conn?net.Conn)?{
????buf?:=?make([]byte,?4096)
????for?{
????????n,?err?:=?conn.Read(buf)
????????if?err?!=?nil?{
????????????fmt.Println(err)
????????????os.Exit(1)

????????}
????????defer?conn.Close()
????????fmt.Println("接收到消息:",?string(buf[:n]))
????????fmt.Println("請(qǐng)輸入要發(fā)送的消息:")
????}
}

func?main()?{
????conn,?err?:=?net.Dial("tcp",?"127.0.0.1:9876")
????if?err?!=?nil?{
????????fmt.Println(err)
????????return
????}
????defer?conn.Close()
????go?readFromServer(conn)
????//fmt.Println("請(qǐng)輸入要發(fā)送的消息:")

????for?{

????????//strs?:=""
????????//?fmt.Scanln(&strs)?空格有問(wèn)題
????????//strs?:=?make([]byte,?4096)

????????//n,?err?:=?os.Stdin.Read(strs)
????????str,?err?:=?bufio.NewReader(os.Stdin).ReadString('\n')
????????if?err?!=?nil?{
????????????fmt.Println(err)
????????}
????????str?=?strings.TrimSpace(str)
????????//fmt.Println("發(fā)送前",?,?"展示")
????????//fmt.Println("a",?str,?"b")
????????if?str?==?"Q"?{
????????????fmt.Println("接收到退出命令,退出客戶端")
????????????break
????????}
????????conn.Write([]byte(str))

????}

}

網(wǎng)頁(yè)名稱:golang聊天室學(xué)習(xí)筆記
當(dāng)前地址:http://weahome.cn/article/ggjggs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部