Golang中国

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

package main

import (
    "fmt"
    "log"
    "net/http"

    "constData"
    "login"
    "chat"
    "register"
)

func main(){

    openHttpListen()
}

func openHttpListen(){
    http.HandleFunc("/",receiveClientRequest)
    fmt.Println("go server start running...")

    err := http.ListenAndServe(":9090",nil)
    if err != nil {
        log.Fatal("ListenAndServe: ",err)
    }
}

func receiveClientRequest(w http.ResponseWriter,r *http.Request){

    r.ParseForm()
    fmt.Println("收到客户端请求: ",r.Form)
    /*
    fmt.Println("path",r.URL.Path)
    fmt.Println("scheme",r.URL.Scheme)
    fmt.Println(r.Form["url_long"])

        for k,v := range r.Form {
            fmt.Printf("----------\n")
            fmt.Println("key:",k)
            fmt.Println("value:",strings.Join(v,", "))
        }
    */
    var tag string = r.FormValue("tag")
    switch tag{
    case constData.REQ_TAG_LOGIN:

        login.ReceiveLogin(w ,r)

    case constData.REQ_TAG_REGISTER:

        register.ReceiveRegister(w,r)

    case constData.REG_TAG_CHAT:

        chat.ReceiveChat(w,r)

    case constData.REQ_TAG_LASTEST_MESSAGE:

        chat.ReceiveMsgReq(w,r)

    default:
        break
    }

}



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  end {
        start, end = end, start
    }

    if start  rl {
        start = rl
    }
    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
}

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"

)

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

6 回复
JM_Joy
#1 JM_Joy • 2015-01-22 23:38

支持了!

bigbear
#2 bigbear • 2015-01-23 12:55

放github分享呗, 有持续性

quella
#3 quella • 2015-01-23 23:55

希望能放github分享

zhuhao
#4 zhuhao • 2015-01-27 22:27

IM推荐用WebSocket

xinyu391
#5 xinyu391 • 2015-01-28 12:59

这玩意,没协议定义,就只当是学go语言练手

devuser
#6 devuser • 2015-01-29 17:19

哪个大神给普及一下unity3d是做什么的呢?

是否有参考案例,类似Qt?

需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。