Lzs 2019-09-08
æ¬æä¸ºå¤§å®¶å享äº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
}以ä¸å°±æ¯æ¬æçå¨é¨å容ï¼å¸æå¯¹å¤§å®¶çå¦ä¹ ææå¸®å©ï¼ä¹å¸æå¤§å®¶å¤å¤æ¯æèæ¬ä¹å®¶ã