日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
創(chuàng)新互聯(lián)GoFrame教程:GoFrame 連接對(duì)象-消息包處理

?gtcp?提供了許多方便的原生操作連接數(shù)據(jù)的方法,但是在絕大多數(shù)的應(yīng)用場(chǎng)景中,開發(fā)者需要自己設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),并進(jìn)行封包/解包處理,由于?TCP?消息協(xié)議是沒有消息邊界保護(hù)的,因此復(fù)雜的網(wǎng)絡(luò)通信環(huán)境中很容易出現(xiàn)粘包的情況。因此?gtcp?也提供了簡(jiǎn)單的數(shù)據(jù)協(xié)議,方便開發(fā)者進(jìn)行消息包交互,開發(fā)者不再需要擔(dān)心消息包的處理細(xì)節(jié),包括封包/解包處理,這一切復(fù)雜的邏輯?gtcp?已經(jīng)幫你處理好了。

簡(jiǎn)單協(xié)議

?gtcp?模塊提供了簡(jiǎn)單輕量級(jí)數(shù)據(jù)交互協(xié)議,效率非常高,協(xié)議格式如下:

數(shù)據(jù)長(zhǎng)度(16bit)|數(shù)據(jù)字段(變長(zhǎng))

  1. 數(shù)據(jù)長(zhǎng)度:默認(rèn)為16位(2字節(jié)),用于標(biāo)識(shí)該消息體的數(shù)據(jù)長(zhǎng)度,單位為字節(jié),不包含自身的2字節(jié);
  2. 數(shù)據(jù)字段:變長(zhǎng),根據(jù)數(shù)據(jù)長(zhǎng)度可以知道,數(shù)據(jù)最大長(zhǎng)度不能超過?0xFFFF = 65535 bytes = 64 KB?;

簡(jiǎn)單協(xié)議由?gtcp?封裝實(shí)現(xiàn),如果開發(fā)者客戶端和服務(wù)端如果都使用?gtcp?模塊來通信則無需關(guān)心協(xié)議實(shí)現(xiàn),專注數(shù)據(jù)字段封裝/解析實(shí)現(xiàn)即可。如果涉及和其他開發(fā)語言對(duì)接,則需要按照該協(xié)議實(shí)現(xiàn)對(duì)接即可,由于簡(jiǎn)單協(xié)議非常簡(jiǎn)單輕量級(jí),因此對(duì)接成本很低。

數(shù)據(jù)字段也可以為空,即沒有任何長(zhǎng)度。

操作方法

https://pkg.GO.dev/github.com/gogf/gf/v2/net/gtcp

type Conn
    func (c *Conn) SendPkg(data []byte, option ...PkgOption) error
    func (c *Conn) SendPkgWithTimeout(data []byte, timeout time.Duration, option ...PkgOption) error
    func (c *Conn) SendRecvPkg(data []byte, option ...PkgOption) ([]byte, error)
    func (c *Conn) SendRecvPkgWithTimeout(data []byte, timeout time.Duration, option ...PkgOption) ([]byte, error)
    func (c *Conn) RecvPkg(option ...PkgOption) (result []byte, err error)
    func (c *Conn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption) ([]byte, error)

可以看到,消息包方法命名是在原有的基本連接操作方法中加上了?Pkg?關(guān)鍵詞便于區(qū)分。

其中,請(qǐng)求參數(shù)中的?PkgOption?數(shù)據(jù)結(jié)構(gòu)如下,用于定義消息包接收策略:

// 數(shù)據(jù)讀取選項(xiàng)
type PkgOption struct {
	HeaderSize  int   // 自定義頭大小(默認(rèn)為2字節(jié),最大不能超過4字節(jié))
	MaxDataSize int   // (byte)數(shù)據(jù)讀取的最大包大小,默認(rèn)最大不能超過2字節(jié)(65535 byte)
	Retry       Retry // 失敗重試策略
}

使用示例

示例1,基本使用

package main

import (
	"fmt"
	"github.com/gogf/gf/v2/net/gtcp"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/util/gconv"
	"time"
)

func main() {
	// Server
	go gtcp.NewServer("127.0.0.1:8999", func(conn *gtcp.Conn) {
		defer conn.Close()
		for {
			data, err := conn.RecvPkg()
			if err != nil {
				fmt.Println(err)
				break
			}
			fmt.Println("receive:", data)
		}
	}).Run()

	time.Sleep(time.Second)

	// Client
	conn, err := gtcp.NewConn("127.0.0.1:8999")
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	for i := 0; i < 10000; i++ {
		if err := conn.SendPkg([]byte(gconv.String(i))); err != nil {
			glog.Error(err)
		}
		time.Sleep(1*time.Second)
	}
}

這個(gè)示例比較簡(jiǎn)單,執(zhí)行后,輸出結(jié)果為:

receive: [48]
receive: [49]
receive: [50]
receive: [51]
...

示例2,自定義數(shù)據(jù)結(jié)構(gòu)

大多數(shù)場(chǎng)景下,我們需要對(duì)發(fā)送的消息能自定義數(shù)據(jù)結(jié)構(gòu),開發(fā)者可以利用數(shù)據(jù)字段傳遞任意的消息內(nèi)容實(shí)現(xiàn)。

以下是一個(gè)簡(jiǎn)單的自定義數(shù)據(jù)結(jié)構(gòu)的示例,用于客戶端上報(bào)當(dāng)前主機(jī)節(jié)點(diǎn)的內(nèi)存及CPU使用情況,示例代碼位于:https://github.com/gogf/gf/v2/tree/master/.example/net/gtcp/pkg_operations/monitor

在該示例中,數(shù)據(jù)字段使用了?JSON?數(shù)據(jù)格式進(jìn)行自定義,便于數(shù)據(jù)的編碼/解碼。

實(shí)際場(chǎng)景中,開發(fā)者往往需要自定義包解析協(xié)議,或者采用較通用的?protobuf?二進(jìn)制包封裝/解析協(xié)議。

  • ?types/types.go?

數(shù)據(jù)結(jié)構(gòu)定義。

package types


import "github.com/gogf/gf/v2/frame/g"


type NodeInfo struct {
    Cpu       float32 // CPU百分比(%)
    Host      string  // 主機(jī)名稱
    Ip        g.Map   // IP地址信息(可能多個(gè))
    MemUsed   int     // 內(nèi)存使用(byte)
    MemTotal  int     // 內(nèi)存總量(byte)
    Time      int     // 上報(bào)時(shí)間(時(shí)間戳)
}

  • ?gtcp_monitor_server.go?

服務(wù)端。

package main


import (
    "encoding/json"
    "github.com/gogf/gf/v2/net/gtcp"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/.example/net/gtcp/pkg_operations/monitor/types"
)


func main() {
    // 服務(wù)端,接收客戶端數(shù)據(jù)并格式化為指定數(shù)據(jù)結(jié)構(gòu),打印
    gtcp.NewServer("127.0.0.1:8999", func(conn *gtcp.Conn) {
        defer conn.Close()
        for {
            data, err := conn.RecvPkg()
            if err != nil {
                if err.Error() == "EOF" {
                    glog.Println("client closed")
                }
                break
            }
            info := &types.NodeInfo{}
            if err := json.Unmarshal(data, info); err != nil {
                glog.Errorf("invalid package structure: %s", err.Error())
            } else {
                glog.Println(info)
                conn.SendPkg([]byte("ok"))
            }
        }
    }).Run()
}

  • ?gtcp_monitor_client.go?

客戶端。

package main


import (
    "encoding/json"
    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/gtcp"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/v2/os/gtime"
    "github.com/gogf/gf/.example/net/gtcp/pkg_operations/monitor/types"
)


func main() {
    // 數(shù)據(jù)上報(bào)客戶端
    conn, err := gtcp.NewConn("127.0.0.1:8999")
    if err != nil {
        panic(err)
    }
    defer conn.Close()
    // 使用JSON格式化數(shù)據(jù)字段
    info, err := json.Marshal(types.NodeInfo{
        Cpu       : float32(66.66),
        Host      : "localhost",
        Ip        : g.Map {
            "etho" : "192.168.1.100",
            "eth1" : "114.114.10.11",
        },
        MemUsed   : 15560320,
        MemTotal  : 16333788,
        Time      : int(gtime.Timestamp()),
    })
    if err != nil {
        panic(err)
    }
    // 使用 SendRecvPkg 發(fā)送消息包并接受返回
    if result, err := conn.SendRecvPkg(info); err != nil {
        if err.Error() == "EOF" {
            glog.Println("server closed")
        }
    } else {
        glog.Println(string(result))
    }
}

  • 執(zhí)行后

客戶端輸出結(jié)果為:

  2019-05-03 13:33:25.710 ok

服務(wù)端輸出結(jié)果為:

  2019-05-03 13:33:25.710 &{66.66 localhost map[eth1:114.114.10.11 etho:192.168.1.100] 15560320 16333788 1556861605}
  2019-05-03 13:33:25.710 client closed

文章標(biāo)題:創(chuàng)新互聯(lián)GoFrame教程:GoFrame 連接對(duì)象-消息包處理
當(dāng)前網(wǎng)址:http://www.5511xx.com/article/ccesiio.html