github.com/rolandhe/saber@v0.0.4/nfour/common.go (about) 1 // tcp network framework 2 // 3 // Copyright 2023 The saber Authors. All rights reserved. 4 5 // Package nfour, tcp 网路工具框架,因为 tcp工作在4层上,所以该包命名为 nfour。包含: 6 // 7 // 1. 多路复用网络模型实现 8 // 9 // 2. 单路复用网络模型实现,即 同步request/response模型 10 // 11 // 3. 基于多路复用的rpc框架 12 // 13 // 4. json encode的多路复用rpc框架 14 package nfour 15 16 import ( 17 "errors" 18 "github.com/rolandhe/saber/gocc" 19 "io" 20 "net" 21 "os" 22 "time" 23 ) 24 25 const ( 26 // PayLoadLenBufLength header中的首4个字节,用于记录header后面数据负载的长度 27 // header格式:4个字节 + 8个字节 + n个字节的payload, 其中首4个字节里存储 n,8个字节表示request id, 最后的n个字节表示request 数据 28 PayLoadLenBufLength = 4 29 ) 30 31 var ( 32 // PeerCloseError 连接的另一头已经关闭连接 33 PeerCloseError = errors.New("peer closed") 34 // ExceedConcurrentError 当前的请求已经超出设定的最大并发数 35 ExceedConcurrentError = errors.New("exceed concurrent") 36 defaultSemaWaitTime = time.Millisecond 37 ) 38 39 // Task 描述一个请求的数据, 这个请求会被封装成Task 交于任务执行器执行 40 type Task struct { 41 // Payload 请求数据,二进制格式,可以被上层业务解析 42 PayLoad []byte 43 } 44 45 // WorkingFunc 请求的处理函数,请求数据会被解析,执行业务逻辑,生成业务结果,业务结果被转换成二进制格式返回 46 type WorkingFunc func(task *Task) ([]byte, error) 47 48 // HandleError 请求在处理过程中可能发生err, HandleError 描述一个err应该被转换成哪种返回结果 49 type HandleError func(err error) []byte 50 51 // NewSrvConf 构建server段的配置 52 // concurrent 服务的最大并发数, 当到达最大并发后,当前请求等待执行的缺省超时时间是 1 毫秒 53 func NewSrvConf(working WorkingFunc, errHandle HandleError, concurrent uint) *SrvConf { 54 return &SrvConf{ 55 working, 56 errHandle, 57 time.Millisecond * 2000, 58 time.Millisecond * 2000, 59 time.Minute * 10, 60 defaultSemaWaitTime, 61 gocc.NewDefaultSemaphore(concurrent), 62 } 63 } 64 65 // NewSrvConfSemaWait 构建server段的配置 66 // 67 // concurrent 服务的最大并发数, 当到达最大并发后,当前请求等待执行的超时时间由 semaWaitTime 指定 68 // 69 // semaWaitTime 当到达最大并发后,当前请求等待执行的超时时间 70 func NewSrvConfSemaWait(working WorkingFunc, errHandle HandleError, concurrent uint, semaWaitTime time.Duration) *SrvConf { 71 if semaWaitTime < 0 { 72 semaWaitTime = defaultSemaWaitTime 73 } 74 return &SrvConf{ 75 working, 76 errHandle, 77 time.Millisecond * 2000, 78 time.Millisecond * 2000, 79 time.Minute * 10, 80 semaWaitTime, 81 gocc.NewDefaultSemaphore(concurrent), 82 } 83 } 84 85 // SrvConf 描述服务端的配置, 包括: 86 // 87 // Working 请求处理函数 88 // 89 // # ErrHandle 出错信息出来 90 // 91 // SemaWaitTime 如果当前已经到达最大并发,当前请求等待被执行的超时时间 92 type SrvConf struct { 93 Working WorkingFunc 94 ErrHandle HandleError 95 ReadTimeout time.Duration 96 WriteTimeout time.Duration 97 IdleTimeout time.Duration 98 SemaWaitTime time.Duration 99 concurrent gocc.Semaphore 100 } 101 102 // GetConcurrent 获取当前服务配置的最大并发数的信号量 103 func (conf *SrvConf) GetConcurrent() gocc.Semaphore { 104 return conf.concurrent 105 } 106 107 // InternalReadPayload 从连接中读取指定长度的数据, 主要是内部使用 108 // notHalt 当长时间读取不到数据且收到超时异常时,是不是不中断连接,true,不中断连接,继续读取 109 func InternalReadPayload(conn net.Conn, buff []byte, expectLen int, notHalt bool) error { 110 l := 0 111 for { 112 n, err := conn.Read(buff) 113 if err != nil { 114 if !notHalt && errors.Is(err, os.ErrDeadlineExceeded) { 115 NFourLogger.InfoLn(err, l) 116 return err 117 } 118 if errors.Is(err, io.EOF) { 119 NFourLogger.InfoLn("peer closed") 120 return PeerCloseError 121 } 122 return err 123 } 124 l += n 125 126 if l == expectLen { 127 break 128 } 129 buff = buff[n:] 130 } 131 return nil 132 }