本人是搞移動客戶端開發的,業餘時間接觸到golang這麼個可愛的囊地鼠,因而就寫了這麼個測試項目:簡易版的聊天系統,功能包括註冊,登錄,羣聊和單聊,無需使用mysql,數據都存在了文本里。本人純粹興趣,先後就幾天搞出來的產物,想到哪裏寫到哪裏,邊查手冊邊寫出來的,因此某些地方會有不合理的地方,但測試過沒有bug,就當爲新手同窗們提供個參考吧,也給手賤點進來的老手們提供個笑料吧 >_<,最起碼能夠知道go裏怎麼作字符串拆分的,go方法返回多個參數是怎麼寫的,go裏json數據時如何解析的,go是怎麼接受客戶端發來的http請求的,go是怎麼獲取本地時間的,go是如何讀寫本地文本的等等:mysql
項目文件結構爲:golang
src/GoStudy/main.gosql
src/GoStudy/user (此爲文本,註冊用戶表)數據庫
src/GoStudy/chat (此爲文本,羣聊消息表)json
src/GoStudy/singleChat (此爲文本,單聊消息表)測試
src/login/login.gourl
src/register/register.gospa
src/chat/chat.go3d
src/constData/constData.gocode
src/tool/databaseTool.go
src/tool/jsonMaker.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 }
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]) }
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 }
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) } }
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 }
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 }
constData.go:
package constData const ( DateFormat string = "2006-01-02 15:04:02" //日期時間格式 DatabaseFile_Chat string = "chat" DatabaseFile_User string = "user" DatabaseFile_SINGLE_CHAT string = "singleChat" REQ_TAG_LOGIN string = "login" REQ_TAG_REGISTER string = "register" REG_TAG_CHAT string = "chat" REQ_TAG_LASTEST_MESSAGE string = "lastestMsg" )
{"id":"10000","nick":"jd","password":"111111"}
{"id":"10001","nick":"zoe","password":"123456"} {"id":"10002","nick":"frank","password":"qqqqqq"}
{"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":"有人在麼"}
{"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