Go语言多人聊天室项目实战
æ¬æ为大家å享äºGoè¯è¨å¤äººè天室项ç®å®æï¼ä¾å¤§å®¶åèï¼å·ä½å容å¦ä¸
åè½éæ±
- å®ç°åæ©
- å®ç°ç¾¤æ©
- å®ç°ç¨æ·ä¸çº¿çå¨ç½éç¥
- å®ç°ç¨æ·æµç§°
- å®ç°è天æ¥å¿çåå¨åæ¥ç
æå¡ç«¯å®ç°
type Client struct { conn net.Conn name string addr string } var ( //客æ·ç«¯ä¿¡æ¯,ç¨æµç§°ä¸ºé® //clientsMap = make(map[string]net.Conn) clientsMap = make(map[string]Client) ) func SHandleError(err error, why string) { if err != nil { fmt.Println(why, err) os.Exit(1) } } func main() { //建ç«æå¡ç«¯çå¬ listener, e := net.Listen("tcp", "127.0.0.1:8888") SHandleError(e, "net.Listen") defer func() { for _, client := range clientsMap { client.conn.Write([]byte("all:æå¡å¨è¿å¥ç»´æ¤ç¶æï¼å¤§å®¶é½æ´æ´ç¡å§ï¼")) } listener.Close() }() for { //循ç¯æ¥å¥ææ女æå conn, e := listener.Accept() SHandleError(e, "listener.Accept") clientAddr := conn.RemoteAddr() //TODO:æ¥æ¶å¹¶ä¿åæµç§° buffer := make([]byte, 1024) var clientName string for { n, err := conn.Read(buffer) SHandleError(err, "conn.Read(buffer)") if n > 0 { clientName = string(buffer[:n]) break } } fmt.Println(clientName + "ä¸çº¿äº") //TODO:å°æ¯ä¸ä¸ªå¥³æå丢å¥map client := Client{conn, clientName, clientAddr.String()} clientsMap[clientName] = client //TODO:ç»å·²ç»å¨çº¿çç¨æ·åéä¸çº¿éç¥ââ使ç¨æµç§° for _, client := range clientsMap { client.conn.Write([]byte(clientName + "ä¸çº¿äº")) } //å¨åç¬çåç¨ä¸ä¸æ¯ä¸ä¸ªå·ä½ç女æåè天 go ioWithClient(client) } //设置ä¼ééåºé»è¾ } //ä¸ä¸ä¸ªClientåIO func ioWithClient(client Client) { //clientAddr := conn.RemoteAddr().String() buffer := make([]byte, 1024) for { n, err := client.conn.Read(buffer) if err != io.EOF { SHandleError(err, "conn.Read") } if n > 0 { msg := string(buffer[:n]) fmt.Printf("%s:%s\n", client.name, msg) //å°å®¢æ·ç«¯è¯´çæ¯ä¸å¥è¯è®°å½å¨ã以ä»çååå½åçæ件éã writeMsgToLog(msg, client) strs := strings.Split(msg, "#") if len(strs) > 1 { //all#hello //zqd#hello //è¦åéçç®æ æµç§° targetName := strs[0] targetMsg := strs[1] //TODO:使ç¨æµç§°å®ä½ç®æ 客æ·ç«¯çConn if targetName == "all" { //群åæ¶æ¯ for _, c := range clientsMap { c.conn.Write([]byte(client.name + ":" + targetMsg)) } } else { //ç¹å¯¹ç¹æ¶æ¯ for key, c := range clientsMap { if key == targetName { c.conn.Write([]byte(client.name + ":" + targetMsg)) //å¨ç¹å¯¹ç¹æ¶æ¯çç®æ 端ä¹è®°å½æ¥å¿ go writeMsgToLog(client.name + ":" + targetMsg,c) break } } } } else { //客æ·ç«¯ä¸»å¨ä¸çº¿ if msg == "exit" { //å°å½å客æ·ç«¯ä»å¨çº¿ç¨æ·ä¸é¤å //åå¶ä»ç¨æ·åéä¸çº¿éç¥ for name, c := range clientsMap { if c == client { delete(clientsMap, name) } else { c.conn.Write([]byte(name + "ä¸çº¿äº")) } } }else if strings.Index(msg,"log@")==0 { //log@all //log@å¼ å¨è filterName := strings.Split(msg, "@")[1] //å客æ·ç«¯åéå®çè天æ¥å¿ go sendLog2Client(client,filterName) } else { client.conn.Write([]byte("å·²éï¼" + msg)) } } } } } //å客æ·ç«¯åéå®çè天æ¥å¿ func sendLog2Client(client Client,filterName string) { //读åè天æ¥å¿ logBytes, e := ioutil.ReadFile("D:/BJBlockChain1801/demos/W4/day1/01ChatRoomII/logs/" + client.name + ".log") SHandleError(e,"ioutil.ReadFile") if filterName != "all"{ //æ¥æ¾ä¸æ个人çèå¤©è®°å½ //ä»å容ä¸çéåºå¸¦æãfilterName#æfilterName:ãçè¡ï¼æ¼æ¥èµ·æ¥ logStr := string(logBytes) targetStr := "" lineSlice := strings.Split(logStr, "\n") for _,lineStr := range lineSlice{ if len(lineStr)>20{ contentStr := lineStr[20:] if strings.Index(contentStr,filterName+"#")==0 || strings.Index(contentStr,filterName+":")==0{ targetStr += lineStr+"\n" } } } client.conn.Write([]byte(targetStr)) }else{ //æ¥è¯¢ææçèå¤©è®°å½ //å客æ·ç«¯åé client.conn.Write(logBytes) } } //å°å®¢æ·ç«¯è¯´çä¸å¥è¯è®°å½å¨ã以ä»çååå½åçæ件éã func writeMsgToLog(msg string, client Client) { //æå¼æ件 file, e := os.OpenFile( "D:/BJBlockChain1801/demos/W4/day1/01ChatRoomII/logs/"+client.name+".log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) SHandleError(e, "os.OpenFile") defer file.Close() //追å è¿å¥è¯ logMsg := fmt.Sprintln(time.Now().Format("2006-01-02 15:04:05"), msg) file.Write([]byte(logMsg)) }
客æ·ç«¯å®ç°
import ( "net" "fmt" "os" "bufio" "io" "flag" ) var ( chanQuit = make(chan bool, 0) conn net.Conn ) func CHandleError(err error, why string) { if err != nil { fmt.Println(why, err) os.Exit(1) } } func main() { //TODO:å¨å½ä»¤è¡åæ°ä¸æºå¸¦æµç§° nameInfo := [3]interface{}{"name", "æ åæ°", "æµç§°"} retValuesMap := GetCmdlineArgs(nameInfo) name := retValuesMap["name"].(string) //æ¨å·è¿æ¥ï¼è·å¾connection var e error conn, e = net.Dial("tcp", "127.0.0.1:8888") CHandleError(e, "net.Dial") defer func() { conn.Close() }() //å¨ä¸æ¡ç¬ç«çåç¨ä¸è¾å¥ï¼å¹¶åéæ¶æ¯ go handleSend(conn,name) //å¨ä¸æ¡ç¬ç«çåç¨ä¸æ¥æ¶æå¡ç«¯æ¶æ¯ go handleReceive(conn) //设置ä¼ééåºé»è¾ <-chanQuit } func handleReceive(conn net.Conn) { buffer := make([]byte, 1024) for { n, err := conn.Read(buffer) if err != io.EOF { CHandleError(err, "conn.Read") } if n > 0 { msg := string(buffer[:n]) fmt.Println(msg) } } } func handleSend(conn net.Conn,name string) { //TODO:åéæµç§°å°æå¡ç«¯ _, err := conn.Write([]byte(name)) CHandleError(err,"conn.Write([]byte(name))") reader := bufio.NewReader(os.Stdin) for { //读åæ åè¾å¥ lineBytes, _, _ := reader.ReadLine() //åéå°æå¡ç«¯ _, err := conn.Write(lineBytes) CHandleError(err, "conn.Write") //æ£å¸¸éåº if string(lineBytes) == "exit" { os.Exit(0) } } } func GetCmdlineArgs(argInfos ...[3]interface{}) (retValuesMap map[string]interface{}) { fmt.Printf("type=%T,value=%v\n", argInfos, argInfos) //åå§åè¿åç»æ retValuesMap = map[string]interface{}{} //é¢å®ä¹ãç¨æ·å¯è½è¾å¥çåç§ç±»åçæéã var strValuePtr *string var intValuePtr *int //é¢å®ä¹ãç¨æ·å¯è½è¾å¥çåç§ç±»åçæéãçå®¹å¨ //ç¨æ·å¯è½è¾å¥å¥½å 个stringåçåæ°å¼ï¼åæ¾å¨å¥½å 个stringåçæéä¸ï¼å°è¿äºåç§ç±»åçæéæ¾å¨åç§ç±»åçmapä¸ //ä¾å¦ï¼flag.Parse()äºä»¥åï¼å¯ä»¥æ ¹æ®ãstrValuePtrsMap["cmd"]ãæ¿å°ãåæ¾"cmd"å¼çæéã var strValuePtrsMap = map[string]*string{} var intValuePtrsMap = map[string]*int{} /* var floatValuePtr *float32 var floatValuePtrsMap []*float32 var boolValuePtr *bool var boolValuePtrsMap []*bool*/ //éåç¨æ·éè¦æ¥åçææå½ä»¤å®ä¹ for _, argArray := range argInfos { /* åææ¯ä¸ªå½ä»¤çå称åç¨æ³æ¿åºæ¥, è¿ä¿©è´§é½æ¯stringç±»åçï¼ææé½å¯ä»¥éè¿argArray[i].(string)è½»æ¾æå¿«å°è·å¾å¶å符串 ä¸ä¸ªå«âcmdâï¼ä¸ä¸ªå«âä½ æ³å¹²åâ "cmd"ä¸ä¼ä¼ç¨ä½mapçkey */ //[3]interface{} //["cmd" "æªç¥ç±»å" "ä½ æ³å¹²å"] //["gid" 0 "è¦æ¥è¯¢çååID"] //ä¸é¢çç ´ç©æç±»å[string å¯è½æ¯ä»»æç±»å string] nameValue := argArray[0].(string) //æ¿å°ç¬¬ä¸ä¸ªåç´ çstringå¼,æ¯å½ä»¤çname usageValue := argArray[2].(string) //æ¿å°æåä¸ä¸ªåç´ çstringå¼ï¼æ¯å½ä»¤çusage //å¤æargArray[1]çå·ä½ç±»å switch argArray[1].(type) { case string: //å¾å°ãåæ¾cmdçæéãï¼cmdçå¼å°å¨flag.Parse()以åæä¼æ //cmdValuePtr = flag.String("cmd", argArray[1].(string), "ä½ æ³å¹²å") strValuePtr = flag.String(nameValue, argArray[1].(string), usageValue) //å°è¿ä¸ªç ´æé以"cmd"为é®ï¼åå¨ãä¸é¨æ¾ç½®stringåæéçmapï¼å³strValuePtrsMapãä¸ strValuePtrsMap[nameValue] = strValuePtr case int: //å¾å°ãåæ¾gidçæéãï¼gidçå¼å°å¨flag.Parse()以åæä¼æ //gidValuePtr = flag.String("gid", argArray[1].(int), "ååID") intValuePtr = flag.Int(nameValue, argArray[1].(int), usageValue) //å°è¿ä¸ªç ´æé以"gid"为é®ï¼åå¨ãä¸é¨æ¾ç½®intåæéçmapï¼å³intValuePtrsMapãä¸ intValuePtrsMap[nameValue] = intValuePtr } } /* ç¨åºè¿è¡å°è¿éï¼ææä¸åç±»åçãåå¼æéãé½æ¾å¨å¯¹ç¸åºç±»åçmapä¸äº flag.Parse()äºä»¥åï¼å¯ä»¥ä»mapä¸ä»¥åæ°ååè·ååºãåå¼æéãï¼è¿èè·å¾ãç¨æ·è¾å¥çå¼ã */ //ç¨æ·è¾å¥å®äºï¼è§£æï¼ãç¨æ·è¾å¥çå¼ãå¨é½æ¾å¨å¯¹åºçãåå¼æéãä¸ flag.Parse() /* éååç§å¯è½ç±»åçãåå¼æéçmapã */ if len(strValuePtrsMap) > 0 { //ä»ãcmdåå¼æéçmapãä¸æ¿åcmdçå¼ï¼è¿ä»¥cmd为é®åå¥ç»æmapä¸ for k, vPtr := range strValuePtrsMap { retValuesMap[k] = *vPtr } } if len(intValuePtrsMap) > 0 { //ä»ãgidåå¼æéçmapãä¸æ¿ågidçå¼ï¼è¿ä»¥gid为é®åå¥ç»æmapä¸ for k, vPtr := range intValuePtrsMap { retValuesMap[k] = *vPtr } } //è¿åç»æmap return }
以ä¸å°±æ¯æ¬æçå¨é¨å容ï¼å¸æ对大家çå¦ä¹ ææ帮å©ï¼ä¹å¸æ大家å¤å¤æ¯æèæ¬ä¹å®¶ã
相关推荐
Lzs 2020-10-23
聚合室 2020-11-16
零 2020-09-18
Justhavefun 2020-10-22
jacktangj 2020-10-14
ChaITSimpleLove 2020-10-06
Andrea0 2020-09-18
周游列国之仕子 2020-09-15
afanti 2020-09-16
88234852 2020-09-15
YClimb 2020-09-15
风雨断肠人 2020-09-04
卖口粥湛蓝的天空 2020-09-15
stulen 2020-09-15
pythonxuexi 2020-09-06
abfdada 2020-08-26
梦的天空 2020-08-25