pitaya学习实践笔记(2)

编程入门 行业动态 更新时间:2024-10-26 02:28:31

pitaya学习实践<a href=https://www.elefans.com/category/jswz/34/1770047.html style=笔记(2)"/>

pitaya学习实践笔记(2)

首先,因为真实的客户端不能做到像pitaya-cli一样通过命令行(connect 127.0.0.1:3250)直接连接到服务器,所以需要我们了解客户端与服务端建立tcp连接的过程以及传输报文结构。

这里我们采用tcp连接工具(网络调试助手)来模拟客户端

1

查看pitaya-cli的源码,找到connect命令调用的函数,根据调用堆栈发现connect函数第一步是执行了sendHandshakeRequest()函数:

改代码直接让main函数调用到这里,发现发送的数据的ASCII码是这个:

\x01\x00\x00z{\"sys\":{\"platform\":\"mac\",\"libVersion\":\"0.3.5-release\",\"clientBuildNumber\":\"20\",\"clientVersion\":\"1.0.0\"},\"user\":{\"age\":30}}"

再根据调用的Encode函数得知,其中\x01=type=1,\x00\x00z=len(data)=122

那么服务端在收到数据后又干了什么呢?

这里我们需要进行源码调试来帮助我们理解。为了方便调试,这里直接将源码的demo(pitaya@v1.1.8\examples\demo\cluster\main.go)作为服务器代码。在整个源码中搜索handshake,找到这个函数:func (h *HandlerService) processPacket(,根据调用堆栈推断这里很有可能是处理客户端发来的handshake数据的地方,打上断点来验证:这里选中并直接F5运行起来服务端与客户端的main.go。服务端收到handshake,并回复客户端(SendHandshakeResponse()函数):

 在整个源码中搜索handshakeResponse,找到这个函数:func (c *Client) handleHandshakeResponse(,并在客户端所在的项目找到它并打上断点。调试得知:客户端收到数据包handshakePacket,其中最重要的是这个Type=1=packet.Handshake表示数据包是handshake类型。

客户端收到handshake:

2

紧接着,客户端又发送Type=2=packet.HandshakeAck的数据包给服务端

(发送的数据的ASCII码是这个:\x02\x00\x00\x00)

 服务端收到HandshakeAck:至此,tcp握手完毕,建立连接成功

客户端打印了connected!表示成功连接了

3

然后调试发送实际业务请求的流程:

客户端main函数添加:

logger := log.New(os.Stdout, "", log.LstdFlags)

executeCommand(logger, "connect 127.0.0.1:3250")

executeCommand(logger, "request connector.connector.getsessiondata")

select {}

其中我们请求了前端服务器connector的getsessiondata函数,在服务端找到并打个断点。根据调用堆栈找到客户端发送业务数据的核心函数:func (c *Client) sendMsg(

找到最终发送出去的数据的ASCII码:

"\x04\x00\x00%\x00\x01\"connector.connector.getsessiondata"

绿色部分:1个byte  对应constans.go文件的常量:Handshake= 0x01等  ,4表示是业务数据

蓝色部分:3个byte=0x25=%    对应"\x00\x01\"connector.connector.getsessiondata"这一串数据的长度=37

红色部分:分别对应结构体message.Message的type,id(每次累加1)

底层消息数据结构:

服务端收到业务数据请求(packet.Data=Type=4 表示业务) 

最终到达GetSessionData()函数

总结

建立连接到发送业务过程:

1  客户端发送handlshake,服务端返回handlshake

2  客户端发送handshakeAck,连接成功

3  最后发业务数据

客户端发送数据(ASCII码):

1  \x01\x00\x00z{\"sys\":{\"platform\":\"mac\",\"libVersion\":\"0.3.5-release\",\"clientBuildNumber\":\"20\",\"clientVersion\":\"1.0.0\"},\"user\":{\"age\":30}}

2  \x02\x00\x00\x00

3  \x04\x00\x00%\x00\x01\"connector.connector.getsessiondata

然后我们直接通过网络调试助手来按照顺序发送以上内容来模拟真实客户端发送情况:

1

2

3

客户端发送的结构体格式:

1

type 1 byte

len 3 byte

type HandshakeData struct {

        Platform    string `json:"platform"`

        LibVersion  string `json:"libVersion"`

        BuildNumber string `json:"clientBuildNumber"`

        Version     string `json:"clientVersion"`

        User map[string]interface{} `json:"user,omitempty"`

}

2

type 1 byte

len 3 byte

3

type 1 byte

len 3 byte

type Message struct {

        Type       Type   // message type

        ID         uint   // unique id, zero while notify mode

        Route      string // route for locating service

        Data       []byte // payload

        compressed bool   // is message compressed

        Err        bool   // is an error message

}

更多推荐

pitaya学习实践笔记(2)

本文发布于:2024-02-17 05:16:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1692788.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:笔记   pitaya

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!