github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/transport/tcp_server.go (about)

     1  package transport
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"time"
     8  )
     9  
    10  type (
    11  	// contextKey is a value for use with context.WithValue. It's used as
    12  	// a pointer so it fits in an interface{} without allocation.
    13  	contextKey struct {
    14  		name string
    15  	}
    16  
    17  	rpcHandler interface {
    18  		ServeRPC(*RpcResponse, *RpcRequest)
    19  	}
    20  
    21  	tcpTransportListener struct {
    22  		listener  net.Listener
    23  		transport *tcpTransport
    24  		sock      *tcpTransportSocket // TODO 还未实现
    25  	}
    26  )
    27  
    28  func (k *contextKey) String() string { return "rpc context value " + k.name }
    29  
    30  var (
    31  	// RemoteConnContextKey is a context key. It can be used in
    32  	// services with context.WithValue to access the connection arrived on.
    33  	// The associated value will be of type net.Conn.
    34  	RemoteConnContextKey = &contextKey{"remote-conn"}
    35  	// StartRequestContextKey records the start time
    36  	StartRequestContextKey = &contextKey{"start-parse-request"}
    37  	// StartSendRequestContextKey records the start time
    38  	StartSendRequestContextKey = &contextKey{"start-send-request"}
    39  )
    40  
    41  func (t *tcpTransportListener) Addr() net.Addr {
    42  	return t.listener.Addr()
    43  }
    44  
    45  func (t *tcpTransportListener) Close() error {
    46  	return t.listener.Close()
    47  }
    48  
    49  func (self *tcpTransportListener) Sock() ISocket {
    50  	return self.sock
    51  }
    52  
    53  func (t *tcpTransportListener) Accept() (net.Conn, error) {
    54  	return t.listener.Accept()
    55  }
    56  
    57  func (self *tcpTransportListener) Serve(handler Handler) error {
    58  	hd, ok := handler.Handler().(rpcHandler)
    59  	if !ok {
    60  		return fmt.Errorf("the handler is not a rpc handler! %v ", handler)
    61  	}
    62  	var tempDelay time.Duration
    63  
    64  	for {
    65  		conn, err := self.listener.Accept()
    66  		if err != nil {
    67  			if ne, ok := err.(net.Error); ok && ne.Temporary() {
    68  				if tempDelay == 0 {
    69  					tempDelay = 5 * time.Millisecond
    70  				} else {
    71  					tempDelay *= 2
    72  				}
    73  				if max := 1 * time.Second; tempDelay > max {
    74  					tempDelay = max
    75  				}
    76  				log.Errf("http: Accept error: %v; retrying in %v\n", err, tempDelay)
    77  				time.Sleep(tempDelay)
    78  				continue
    79  			}
    80  			return err
    81  		}
    82  
    83  		sock := NewTcpTransportSocket(conn, self.transport.config.ReadTimeout, self.transport.config.WriteTimeout)
    84  
    85  		go func() {
    86  			//@ 获取空白通讯包
    87  			msg := GetMessageFromPool() // request message
    88  
    89  			// TODO: think of a better error response strategy
    90  			defer func() {
    91  				if r := recover(); r != nil {
    92  					sock.Close()
    93  				}
    94  
    95  				PutMessageToPool(msg)
    96  			}()
    97  
    98  			// TODO 自定义通讯包结构
    99  			// 获得请求参数
   100  			err = msg.Decode(conn) // 等待读取客户端信号
   101  			if err != nil {
   102  				//return err
   103  				// TODO
   104  			}
   105  
   106  			ctx := context.WithValue(context.Background(), RemoteConnContextKey, conn)
   107  
   108  			req := NewRpcRequest(ctx, msg, sock)
   109  			rsp := NewRpcResponse(ctx, req, sock)
   110  
   111  			hd.ServeRPC(rsp, req)
   112  		}()
   113  	}
   114  }