本人是搞移动客户端开发的,业余时间接触到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
有疑问加站长微信联系(非本文作者)