golang tcp framework,golang tcp框架

一款易用高效的tcp框架

https://github.com/fwhezfwhez/tcpx

1. 简述

golang 原生库提供对tcp支持,但使用者需要自定义协议,自主拆包解包,不同开发者对tcp的架构五花八门,群魔乱舞。tcpx是一款轻便简约的tcp框架,自备协议并支持传统的json,xml,toml,yaml,protobuf序列方式,也支持自定义序列方式。使用tcpx后,无需考虑自主拆包解包,也无粘包问题,对tcp的使用方式,也有了一定意义上的统一,利于团队开发。

2. 协议概述

tcpx协议块分为

块名类型含义序列方式大小
Lenint32块长大端拼接[4]byte
MessageIDint32块标识大端拼接[4]byte
HeaderLenint32头部长大端拼接[4]byte
BodyLenint32消息长大端拼接[4]byte
Headermap[string]interface{}头部内容json[]byte
Bodyinterface{}消息内容自定义序列化(json,xml,toml,yaml,protobuf,其它自定义)[]byte

3. tcpx 特性

3.1 无需拆/组包

原生tcp库的net.Conn对收发的消息内容是源源不断的,并且只保证消息的先后顺序,比如一方发送两则消息[0 11 13 99 123] 与[2 12 23 43 99 23]时,另一方只保证收到[0 11 13 99 123 2 12 23 43 99 23],接收方需要按照协议体,将其拆分成两段有效的消息内容。
因为tcpx是严格按照协议头记录的Len 长度拆组包,拆包时精准且不会出现粘包情况。

3.2 自带messageID路由与强大的中间件套餐

tcpx 的协议设计里存在messageID,便是用来对消息处理逻辑的划分的。使用者无需按照传统(当然也不反对)的方式,对tcp服务方收到的消息进行类似如下操作:

switch messageID {
    case 1 : 
        service1()
    case 2 :
        service2()
    ...
}

tcpx自带messageID路由功能,使用时可以直接这样操作:

func main(){
    	srv := tcpx.NewTcpX(tcpx.JsonMarshaller{})
   		srv.AddHandler(1, service1)
 		srv.AddHandler(2, service2)
 		srv.ListenAndServe("tcp", ":7171");
}

基于路由功能时,可以使用强大的中间件套餐

func main(){
    	srv := tcpx.NewTcpX(tcpx.JsonMarshaller{})
    	srv.Use("middleware1", Middleware1)
   		srv.AddHandler(1, service1)
 		srv.AddHandler(2, service2)
 		srv.ListenAndServe("tcp", ":7171")
}

func Middleware1(c *tcpx.Context) {
	fmt.Println("I am middleware 1 exampled by 'srv.Use(\"middleware1\", Middleware1)'")
}

中间件添加方式有以下三种方式:
srv.Use("middleware1", Middleware1)
srv.UseGlobal(Middleware1)
srv.AddHandler(2, Middleware1,service2)

传统的写法并未摒弃:

func main(){
	srv := tcpx.NewTcpX(tcpx.JsonMarshaller{})
	srv.OnMessage = OnMessage
	srv.ListenAndServe("tcp", ":7171")
}
func OnMessage(c *tcpx.Context) {
	type ServiceA struct {
		Username string `json:"username"`
	}
	type ServiceB struct {
		ServiceName string `json:"service_name"`
	}

	messageID, e := packx.MessageIDOf(c.Stream)
	if e != nil {
		fmt.Println(errorx.Wrap(e).Error())
		return
	}

	switch messageID {
	case 7:
		var serviceA ServiceA
		// block, e := packx.Unpack(c.Stream, &serviceA)
		block, e := c.Bind(&servcieA)
		fmt.Println(block, e)
		c.Reply(8, "success")
	case 9:
		var serviceB ServiceB
		// block, e := packx.Unpack(c.Stream, &serviceB)
	    block, e := c.Bind(&servcieB)
		fmt.Println(block, e)
		c.JSON(10, "success")
	}
}

3.3协议跨语言

了解了协议内容后,不同的语言构建客户端时有两种方式,一种是手动构建(#2)描述的tcpx协议块,另一种是通过http网关构建协议块。
前者不多描述,后者的链接: https://github.com/fwhezfwhez/tcpx/tree/master/gateway/pack-transfer

网关程序为go编写,支持跨平台,可在mac,linux,windows不同位上完美运行。
网关程序本地运行后,生成协议块时,只需要http调用:

4. 实例

https://github.com/fwhezfwhez/tcpx/tree/master/examples/sayHello

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值