zoukankan      html  css  js  c++  java
  • 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("----------
    ")
    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,"
    ")
        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,"
    ")
            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) +
                    "}
    "
            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,"
    ")
            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) +
                    "}
    "
    
            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,"
    ")
            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) +
                    "}
    "
    
            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,"
    ")
    
                //    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,"
    ")
                //    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
    ",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
    ",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
    }
    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"
    )
    

     

     

    三个文本内容格式:

    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

  • 相关阅读:
    获取windows所有用户名
    windbg内存查看(d*)
    Windbg查看调用堆栈(k*)
    Windbg调试互斥体(Mutex)死锁
    Windbg调试关键区(CriticalSection)死锁
    "R6002 floating point support not loaded"错误
    由可变参数引起的崩溃
    【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现
    jdk1.8源码解析(1):HashMap源码解析
    Java annotation浅析
  • 原文地址:https://www.cnblogs.com/JD85/p/4253711.html
Copyright © 2011-2022 走看看