github.com/evdatsion/aphelion-dpos-bft@v0.32.1/abci/server/socket_server.go (about) 1 package server 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "net" 8 "sync" 9 10 "github.com/evdatsion/aphelion-dpos-bft/abci/types" 11 cmn "github.com/evdatsion/aphelion-dpos-bft/libs/common" 12 ) 13 14 // var maxNumberConnections = 2 15 16 type SocketServer struct { 17 cmn.BaseService 18 19 proto string 20 addr string 21 listener net.Listener 22 23 connsMtx sync.Mutex 24 conns map[int]net.Conn 25 nextConnID int 26 27 appMtx sync.Mutex 28 app types.Application 29 } 30 31 func NewSocketServer(protoAddr string, app types.Application) cmn.Service { 32 proto, addr := cmn.ProtocolAndAddress(protoAddr) 33 s := &SocketServer{ 34 proto: proto, 35 addr: addr, 36 listener: nil, 37 app: app, 38 conns: make(map[int]net.Conn), 39 } 40 s.BaseService = *cmn.NewBaseService(nil, "ABCIServer", s) 41 return s 42 } 43 44 func (s *SocketServer) OnStart() error { 45 if err := s.BaseService.OnStart(); err != nil { 46 return err 47 } 48 ln, err := net.Listen(s.proto, s.addr) 49 if err != nil { 50 return err 51 } 52 s.listener = ln 53 go s.acceptConnectionsRoutine() 54 return nil 55 } 56 57 func (s *SocketServer) OnStop() { 58 s.BaseService.OnStop() 59 if err := s.listener.Close(); err != nil { 60 s.Logger.Error("Error closing listener", "err", err) 61 } 62 63 s.connsMtx.Lock() 64 defer s.connsMtx.Unlock() 65 for id, conn := range s.conns { 66 delete(s.conns, id) 67 if err := conn.Close(); err != nil { 68 s.Logger.Error("Error closing connection", "id", id, "conn", conn, "err", err) 69 } 70 } 71 } 72 73 func (s *SocketServer) addConn(conn net.Conn) int { 74 s.connsMtx.Lock() 75 defer s.connsMtx.Unlock() 76 77 connID := s.nextConnID 78 s.nextConnID++ 79 s.conns[connID] = conn 80 81 return connID 82 } 83 84 // deletes conn even if close errs 85 func (s *SocketServer) rmConn(connID int) error { 86 s.connsMtx.Lock() 87 defer s.connsMtx.Unlock() 88 89 conn, ok := s.conns[connID] 90 if !ok { 91 return fmt.Errorf("Connection %d does not exist", connID) 92 } 93 94 delete(s.conns, connID) 95 return conn.Close() 96 } 97 98 func (s *SocketServer) acceptConnectionsRoutine() { 99 for { 100 // Accept a connection 101 s.Logger.Info("Waiting for new connection...") 102 conn, err := s.listener.Accept() 103 if err != nil { 104 if !s.IsRunning() { 105 return // Ignore error from listener closing. 106 } 107 s.Logger.Error("Failed to accept connection: " + err.Error()) 108 continue 109 } 110 111 s.Logger.Info("Accepted a new connection") 112 113 connID := s.addConn(conn) 114 115 closeConn := make(chan error, 2) // Push to signal connection closed 116 responses := make(chan *types.Response, 1000) // A channel to buffer responses 117 118 // Read requests from conn and deal with them 119 go s.handleRequests(closeConn, conn, responses) 120 // Pull responses from 'responses' and write them to conn. 121 go s.handleResponses(closeConn, conn, responses) 122 123 // Wait until signal to close connection 124 go s.waitForClose(closeConn, connID) 125 } 126 } 127 128 func (s *SocketServer) waitForClose(closeConn chan error, connID int) { 129 err := <-closeConn 130 if err == io.EOF { 131 s.Logger.Error("Connection was closed by client") 132 } else if err != nil { 133 s.Logger.Error("Connection error", "error", err) 134 } else { 135 // never happens 136 s.Logger.Error("Connection was closed.") 137 } 138 139 // Close the connection 140 if err := s.rmConn(connID); err != nil { 141 s.Logger.Error("Error in closing connection", "error", err) 142 } 143 } 144 145 // Read requests from conn and deal with them 146 func (s *SocketServer) handleRequests(closeConn chan error, conn net.Conn, responses chan<- *types.Response) { 147 var count int 148 var bufReader = bufio.NewReader(conn) 149 for { 150 151 var req = &types.Request{} 152 err := types.ReadMessage(bufReader, req) 153 if err != nil { 154 if err == io.EOF { 155 closeConn <- err 156 } else { 157 closeConn <- fmt.Errorf("Error reading message: %v", err.Error()) 158 } 159 return 160 } 161 s.appMtx.Lock() 162 count++ 163 s.handleRequest(req, responses) 164 s.appMtx.Unlock() 165 } 166 } 167 168 func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types.Response) { 169 switch r := req.Value.(type) { 170 case *types.Request_Echo: 171 responses <- types.ToResponseEcho(r.Echo.Message) 172 case *types.Request_Flush: 173 responses <- types.ToResponseFlush() 174 case *types.Request_Info: 175 res := s.app.Info(*r.Info) 176 responses <- types.ToResponseInfo(res) 177 case *types.Request_SetOption: 178 res := s.app.SetOption(*r.SetOption) 179 responses <- types.ToResponseSetOption(res) 180 case *types.Request_DeliverTx: 181 res := s.app.DeliverTx(*r.DeliverTx) 182 responses <- types.ToResponseDeliverTx(res) 183 case *types.Request_CheckTx: 184 res := s.app.CheckTx(*r.CheckTx) 185 responses <- types.ToResponseCheckTx(res) 186 case *types.Request_Commit: 187 res := s.app.Commit() 188 responses <- types.ToResponseCommit(res) 189 case *types.Request_Query: 190 res := s.app.Query(*r.Query) 191 responses <- types.ToResponseQuery(res) 192 case *types.Request_InitChain: 193 res := s.app.InitChain(*r.InitChain) 194 responses <- types.ToResponseInitChain(res) 195 case *types.Request_BeginBlock: 196 res := s.app.BeginBlock(*r.BeginBlock) 197 responses <- types.ToResponseBeginBlock(res) 198 case *types.Request_EndBlock: 199 res := s.app.EndBlock(*r.EndBlock) 200 responses <- types.ToResponseEndBlock(res) 201 default: 202 responses <- types.ToResponseException("Unknown request") 203 } 204 } 205 206 // Pull responses from 'responses' and write them to conn. 207 func (s *SocketServer) handleResponses(closeConn chan error, conn net.Conn, responses <-chan *types.Response) { 208 var count int 209 var bufWriter = bufio.NewWriter(conn) 210 for { 211 var res = <-responses 212 err := types.WriteMessage(res, bufWriter) 213 if err != nil { 214 closeConn <- fmt.Errorf("Error writing message: %v", err.Error()) 215 return 216 } 217 if _, ok := res.Value.(*types.Response_Flush); ok { 218 err = bufWriter.Flush() 219 if err != nil { 220 closeConn <- fmt.Errorf("Error flushing write buffer: %v", err.Error()) 221 return 222 } 223 } 224 count++ 225 } 226 }