本人是搞移动客户端开发的,业余时间接触到golang这么个可爱的囊地鼠,于是就写了这么个测试项目:简易版的聊天系统,功能包括注册,登陆,群聊和单聊,无需使用mysql,数据都存在了文本里。本人纯粹兴趣,前后就几天搞出来的产物,想到哪里写到哪里,边查手册边写出来的,所以某些地方会有不合理的地方,但测试过没有bug,就当为新手同学们提供个参考吧,也给手贱点进来的老手们提供个笑料吧 >_<,最起码可以知道go里怎么做字符串拆分的,go方法返回多个参数是怎么写的,go里json数据时如何解析的,go是怎么接受客户端发来的http请求的,go是怎么获取本地时间的,go是如何读写本地文本的等等:
项目文件结构为:
src/GoStudy/main.go
src/GoStudy/user (此为文本,注册用户表)
src/GoStudy/chat (此为文本,群聊消息表)
src/GoStudy/singleChat (此为文本,单聊消息表)
src/login/login.go
src/register/register.go
src/chat/chat.go
src/constData/constData.go
src/tool/databaseTool.go
src/tool/jsonMaker.go
以下是代码:
main.go:
1 package main 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 8 "constData" 9 "login" 10 "chat" 11 "register" 12 ) 13 14 func main(){ 15 16 openHttpListen() 17 } 18 19 func openHttpListen(){ 20 http.HandleFunc("/",receiveClientRequest) 21 fmt.Println("go server start running...") 22 23 err := http.ListenAndServe(":9090",nil) 24 if err != nil { 25 log.Fatal("ListenAndServe: ",err) 26 } 27 } 28 29 func receiveClientRequest(w http.ResponseWriter,r *http.Request){ 30 31 r.ParseForm() 32 fmt.Println("收到客户端请求: ",r.Form) 33 /* 34 fmt.Println("path",r.URL.Path) 35 fmt.Println("scheme",r.URL.Scheme) 36 fmt.Println(r.Form["url_long"]) 37 38 for k,v := range r.Form { 39 fmt.Printf("----------\n") 40 fmt.Println("key:",k) 41 fmt.Println("value:",strings.Join(v,", ")) 42 } 43 */ 44 var tag string = r.FormValue("tag") 45 switch tag{ 46 case constData.REQ_TAG_LOGIN: 47 48 login.ReceiveLogin(w ,r) 49 50 case constData.REQ_TAG_REGISTER: 51 52 register.ReceiveRegister(w,r) 53 54 case constData.REG_TAG_CHAT: 55 56 chat.ReceiveChat(w,r) 57 58 case constData.REQ_TAG_LASTEST_MESSAGE: 59 60 chat.ReceiveMsgReq(w,r) 61 62 default: 63 break 64 } 65 66 }
login.go:
package login import ( "fmt" "net/http" "strings" "encoding/json" "io" "log" "tool" "constData" ) var totalNickStr string func ReceiveLogin(w http.ResponseWriter,r *http.Request) { var nick string = r.FormValue("nick") var password string = r.FormValue("password") var tempData string = "" var userID string = checkUserDataExist(nick,password) if userID != "" { //登陆成功返回用户id,和当前数据库内所有用户信息 tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_LOGIN) + "," + tool.MakeJsonValue("result","1") + "," + tool.MakeJsonValue("id",userID) + "," + tool.MakeJsonValue1("userlist",totalNickStr) + "}" } else { //返回client登录失败,用户不存在 0 tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_LOGIN) + "," + tool.MakeJsonValue("result","0") + "," + tool.MakeJsonValue("info","账号不存在,请重新输入或者注册一个新账号") + "}" } fmt.Fprintf(w,tempData) } func checkUserDataExist(nick string,password string) string { var currentLocalChat string = tool.ReadLocalFile(constData.DatabaseFile_User) var currentLocalChatList []string = strings.Split(currentLocalChat,"\n") var currentLocalChatLength int = len(currentLocalChatList) var count = 0; totalNickStr = "[" for _,str := range currentLocalChatList { totalNickStr += str; count++; if count < (currentLocalChatLength-1) { totalNickStr += ","; } if count == currentLocalChatLength { break } } totalNickStr += "]" type Message struct { ID, Nick, Password string } var existUserID string = ""; dec := json.NewDecoder(strings.NewReader(currentLocalChat)) for { var m Message if err := dec.Decode(&m); err == io.EOF { break } else if err != nil { log.Fatal(err) } var u string = m.Nick var p string = m.Password if u == nick && p == password { existUserID = m.ID } } return existUserID } func Substr(str string, start, length int) string { rs := []rune(str) rl := len(rs) end := 0 if start < 0 { start = rl - 1 + start } end = start + length if start > end { start, end = end, start } if start < 0 { start = 0 } if start > rl { start = rl } if end < 0 { end = 0 } if end > rl { end = rl } return string(rs[start:end]) }
register.go:
package register import ( "net/http" "fmt" "strings" "io" "log" "strconv" "tool" "constData" "encoding/json" ) var localUserData string func ReceiveRegister(w http.ResponseWriter,r *http.Request){ var nick string = r.FormValue("nick") var password string = r.FormValue("password") var tempData string = "" if checknickExist(nick) { //注册失败 tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_REGISTER) + "," + tool.MakeJsonValue("result","0") + "," + tool.MakeJsonValue("info","用户id:"+nick+"已被使用") + "}" } else { //注册成功 var tempList []string = strings.Split(localUserData,"\n") var localUserCount int = len(tempList) var currentUserID string if localUserCount == 0 { currentUserID = "10000" }else { currentUserID = strconv.Itoa(10000 + localUserCount - 1); } tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_REGISTER) + "," + tool.MakeJsonValue("result","1") + "," + tool.MakeJsonValue("id",currentUserID) + "}" //把新账号入库 {"id:",10000"nick":"kate","password":"123abc"} var newUserData string = "{" + tool.MakeJsonValue("id",currentUserID) + "," + tool.MakeJsonValue("nick",nick) + "," + tool.MakeJsonValue("password",password) + "}\n" tool.WriteLocalFile(localUserData + newUserData,constData.DatabaseFile_User); } fmt.Fprintf(w,tempData) } func checknickExist(nick string) bool { localUserData = tool.ReadLocalFile(constData.DatabaseFile_User) type Message struct { Nick, Password string } dec := json.NewDecoder(strings.NewReader(localUserData)) for { var m Message if err := dec.Decode(&m); err == io.EOF { break } else if err != nil { log.Fatal(err) } var u string = m.Nick if u == nick { return true } } return false }
chat.go:
package chat import ( "net/http" "fmt" "strings" "time" "strconv" "encoding/json" "tool" "constData" ) //收到客户度发送的一条聊天信息 func ReceiveChat(w http.ResponseWriter,r *http.Request){ //对方的userid var chatToUserID string = r.FormValue("chatToUserID") var userid string = r.FormValue("userid") var nick string = r.FormValue("nick") var content string = r.FormValue("content") //读取本地时间 currentTime := time.Now() var timeStr string = currentTime.Format(constData.DateFormat) //获取当前本地聊天内容 if chatToUserID == "100" { var currentLocalChat string = tool.ReadLocalFile(constData.DatabaseFile_Chat) var currentLocalChatList []string = strings.Split(currentLocalChat,"\n") var currentLocalChatLength int = len(currentLocalChatList) //组合json形式字符串存入本地 var currentChatData string = "{" + tool.MakeJsonValue("id",strconv.Itoa(currentLocalChatLength - 1)) + "," + tool.MakeJsonValue("time",timeStr) + "," + tool.MakeJsonValue("userid",userid) + "," + tool.MakeJsonValue("nick",nick) + "," + tool.MakeJsonValue("content",content) + "}\n" fmt.Println("新聊天数据:" + currentChatData) var writeSuccess bool = tool.WriteLocalFile(currentChatData + currentLocalChat,constData.DatabaseFile_Chat); var tempData string = "" if writeSuccess { tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.DatabaseFile_Chat) + "," + tool.MakeJsonValue("result","1") + "}" } else { tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.DatabaseFile_Chat) + "," + tool.MakeJsonValue("result","0") + "," + tool.MakeJsonValue("info","聊天信息入库出错") + "}" } fmt.Fprintf(w, tempData) } else { var currentLocalChat string = tool.ReadLocalFile(constData.DatabaseFile_SINGLE_CHAT) var currentLocalChatList []string = strings.Split(currentLocalChat,"\n") var currentLocalChatLength int = len(currentLocalChatList) //组合json形式字符串存入本地 var currentChatData string = "{" + tool.MakeJsonValue("id",strconv.Itoa(currentLocalChatLength - 1)) + "," + tool.MakeJsonValue("time",timeStr) + "," + tool.MakeJsonValue("senderid",userid) + "," + tool.MakeJsonValue("receiverid",chatToUserID) + "," + tool.MakeJsonValue("content",content) + "}\n" fmt.Println("新聊天数据:" + currentChatData) var writeSuccess bool = tool.WriteLocalFile(currentChatData + currentLocalChat,constData.DatabaseFile_SINGLE_CHAT); var tempData string = "" if writeSuccess { tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.DatabaseFile_Chat) + "," + tool.MakeJsonValue("result","1") + "}" } else { tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.DatabaseFile_Chat) + "," + tool.MakeJsonValue("result","0") + "," + tool.MakeJsonValue("info","聊天信息入库出错") + "}" } fmt.Fprintf(w, tempData) } } //收到客户端发送的请求最新几条聊天内容协议 func ReceiveMsgReq(w http.ResponseWriter,r *http.Request){ maxCount,_ := strconv.Atoi(r.FormValue("count")) var chatUserID string = r.FormValue("chatuserid") var selfid string = r.FormValue("selfid") if chatUserID == "100"{ //获取当前本地聊天内容 var currentLocalChat string = tool.ReadLocalFile(constData.DatabaseFile_Chat) var tempData string if currentLocalChat == "noExist" { tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_LASTEST_MESSAGE) + "," + tool.MakeJsonValue("result","0") + "," + tool.MakeJsonValue("chatuserid",chatUserID) + "," + tool.MakeJsonValue("info","聊天信息不存在") + "}" } else { var currentLocalChatList []string = strings.Split(currentLocalChat,"\n") // var currentLocalChatLength int = len(currentLocalChatList) var count = 0; var tempStr = "[" for _,str := range currentLocalChatList { // fmt.Println(index,str) tempStr += str; count++; if count < (maxCount - 1) { tempStr += ","; } if count == maxCount { break } } tempStr += "]" tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_LASTEST_MESSAGE) + "," + tool.MakeJsonValue("result","1") + "," + tool.MakeJsonValue("chatuserid",chatUserID) + "," + tool.MakeJsonValue1("info",tempStr) + "}" } fmt.Fprintf(w, tempData) } else { //获取当前本地聊天内容 var currentLocalChat string = tool.ReadLocalFile(constData.DatabaseFile_SINGLE_CHAT) var tempData string if currentLocalChat == "noExist" { tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_LASTEST_MESSAGE) + "," + tool.MakeJsonValue("result","0") + "," + tool.MakeJsonValue("chatuserid",chatUserID) + "," + tool.MakeJsonValue("info","聊天信息不存在") + "}" } else { var currentLocalChatList []string = strings.Split(currentLocalChat,"\n") // var currentLocalChatLength int = len(currentLocalChatList) var count = 0; var tempStr = "[" for _,str := range currentLocalChatList { // fmt.Println(index,str) type Message struct { ID, Time, Senderid,Receiverid,Content string } dec := json.NewDecoder(strings.NewReader(str)) var m Message dec.Decode(&m) var senderid string = m.Senderid var receiverid string = m.Receiverid if (senderid == selfid && receiverid == chatUserID) || (senderid == chatUserID && receiverid == selfid) { tempStr += str; count++; if count < (maxCount - 1) { tempStr += ","; } if count == maxCount { break } } else { continue } } tempStr += "]" tempData = "{" + tool.MakeJsonValue("code","success") + "," + tool.MakeJsonValue("tag",constData.REQ_TAG_LASTEST_MESSAGE) + "," + tool.MakeJsonValue("result","1") + "," + tool.MakeJsonValue("chatuserid",chatUserID) + "," + tool.MakeJsonValue1("info",tempStr) + "}" } fmt.Fprintf(w, tempData) } }
databaseTool.go:
package tool import ( "fmt" "io/ioutil" ) func ReadLocalFile(filePath string) string { f,err := ioutil.ReadFile(filePath) if err != nil{ fmt.Printf("读表错误: %s\n",err) // panic(err) return "notExist" } return string(f) } func WriteLocalFile(val string,filePath string) bool { var content = []byte(val); err := ioutil.WriteFile(filePath,content,0644) if err != nil{ fmt.Printf("%s\n",err) panic(err) return false } fmt.Println("==写文件成功: " + filePath + "==") return true }
jsonMaker.go:
package tool func MakeJsonValue(key string,val string) string { var str string = "\"" + key + "\":" + "\"" + val + "\"" return str } //value不带双引号 func MakeJsonValue1(key string,val string) string { var str string = "\"" + key + "\":" + "" + val + "" return str }
三个文本内容格式:
user:
{"id":"10000","nick":"jd","password":"111111"} {"id":"10001","nick":"zoe","password":"123456"} {"id":"10002","nick":"frank","password":"qqqqqq"}
chat:
{"id":"3","time":"2015-01-22 15:14:22","userid":"10001","nick":"zoe","content":"就我两么"} {"id":"2","time":"2015-01-22 15:11:22","userid":"10001","nick":"zoe","content":"我来了"} {"id":"1","time":"2015-01-22 15:08:22","userid":"10000","nick":"jd","content":"我好无聊 谁和我聊聊天呀?"} {"id":"0","time":"2015-01-22 15:06:22","userid":"10000","nick":"jd","content":"有人在么"}
singlechat:
{"id":"3","time":"2015-01-22 15:27:22","senderid":"10002","receiverid":"10000","content":"yes ,how do u know that?"} {"id":"2","time":"2015-01-22 15:25:22","senderid":"10000","receiverid":"10002","content":"are you from usa?"} {"id":"1","time":"2015-01-22 15:16:22","senderid":"10001","receiverid":"10000","content":"是的 怎么了"} {"id":"0","time":"2015-01-22 15:15:22","senderid":"10000","receiverid":"10001","content":"你是女孩?"}
另外:
客户端代码就不放上来了,如果需有可以向我要,是unity3d的客户端,我邮箱:jia_ding@qq.com