golang中使用WebSocket实时聊天室和自己写的模拟客户端代码记录

原文地址:http://blog.csdn.net/wangshubo1989/article/details/78250790
使用到的golang包:gorilla/websocket

关于golang的websocket的使用,上述地址的文章讲解比较详细,大家自己去看。
在此仅记录自己的理解:

package main

import (
    "fmt"
    "github.com/gorilla/websocket"
    GOOGLE_PROTO "github.com/golang/protobuf/proto"
    "proto"
    "flag"
    "net/url"
    "encoding/binary"
    "bytes"
)

//关注该代码
var addr = flag.String("addr","localhost:57579","http service address")


func main() {
//关注该代码
u:=url.URL{Scheme:"ws",Host:*addr,Path:"/ws"}
    

    var dialer *websocket.Dialer

        //关注该代码
    conn,_,err:=dialer.Dial(u.String(),nil)
    if err != nil{
        fmt.Println(err)
        return
    }

    timeWriter(conn)

    for {
        var recvBuf []byte
              //关注该代码
               messageType,message,err :=conn.ReadMessage()
        if err != nil{
            fmt.Println("read:",err)
            return
        }

        recvBuf = append(recvBuf, message...)

        if (messageType != websocket.BinaryMessage) {
            continue
        }
        var recvbuf_len int32
        recvbuf_len = int32(len(recvBuf))

        fmt.Printf("recvbuf_len=%d\n",recvbuf_len)
        // 接收数据
        for recvbuf_len >= PKG_HEAD_LEN { // 粘包循环处理
            var head Head
            buf_read := bytes.NewBuffer(recvBuf[:PKG_HEAD_LEN])
            err := binary.Read(buf_read, binary.BigEndian, &head)
            if err != nil {
                break
            }
            if head.PkgFlag == ']' {
                if recvbuf_len >= head.PkgLen {
                    if protocol.Cmd(head.PkgCmd) == protocol.Cmd_CMD_KEEPALIVE_C2S {
                    } else {
                        pkg_len := head.PkgLen - PKG_HEAD_LEN
                        newbuffer := make([]byte, pkg_len)
                        copy(newbuffer, recvBuf[PKG_HEAD_LEN:head.PkgLen])

                        fmt.Printf("pkg_len=%d,newbuffer=%v",pkg_len,newbuffer)
                    }
                    recvBuf = recvBuf[head.PkgLen:]
                    recvbuf_len = int32(len(recvBuf))
                } else { // 半包,继续接收
                    break
                }
            } else { // 错误包边界。。。暂时这么处理?不过也可以直接断开连接。
                fmt.Println("headflag=%d",head.PkgFlag)
                fmt.Println("client read error!!!")
                recvBuf = make([]byte,0)
                recvbuf_len = int32(0)
            }
        }
    }
}

func timeWriter(conn *websocket.Conn) {
    conn.WriteMessage(websocket.BinaryMessage, LoginData())
    conn.WriteMessage(websocket.BinaryMessage, HistData())
}



func HistData()  []byte{
    histData:=&protocol.ReqHist{}
    histData.Gid=GOOGLE_PROTO.Int64(10000001)

    pack,err :=PacketMessage(protocol.Cmd(protocol.Cmd_CMD_HIST_C2S2C),histData)
    if err != nil{
        fmt.Println(err.Error())
    }

    return pack
}

func LoginData() []byte {
    loginData:=&protocol.ReqLogin{}
    loginData.Token=GOOGLE_PROTO.String("123456")

    pack,err :=PacketMessage(protocol.Cmd(protocol.Cmd_CMD_LOGIN_C2S2C),loginData)
    if err != nil{
        fmt.Println(err.Error())
    }

    return pack
}

以上代码是自己在做客户端模拟时写的部分测试代码,因为markdown不是很方便,代码高亮不容易实现,所以用“//关注代码”标注,这几句是websocket客户端接收和发送消息的关键代码。另外需要注意的是引用的包是"github.com/gorilla/websocket"。

你可能感兴趣的:(golang中使用WebSocket实时聊天室和自己写的模拟客户端代码记录)