GO简易聊天系统后台源码分享

本人是搞移动客户端开发的,业余时间接触到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

本文来自:博客园

感谢作者:JD85

查看原文:GO简易聊天系统后台源码分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。