// Handles the actual incoming commands: func (d *Server) handleCommand(ctx context.Context, cmd *wire.Command, p *protocol.Protocol) { ctx, cancel := context.WithCancel(ctx) defer cancel() // Figure out which handler to call: handler, ok := handlerMap[cmd.CommandType] if !ok { log.Warningf("No handler for ID: %v", cmd.CommandType) return } resp, err := handler(d, ctx, cmd) // Empty response or error response: if resp == nil { resp = &wire.Response{} } resp.ResponseType = cmd.CommandType resp.Success = false if err != nil { resp.Error = err.Error() } else { resp.Success = true } // Send the response back to the client: if err := p.Send(resp); err != nil { log.Warning("Unable to send response back to client: ", err) } }
func (lay *Layer) loopServerConn(prot *protocol.Protocol) bool { // Check if we need to quit: select { case <-lay.childCtx.Done(): return false default: break } req := wire.Request{} if err := prot.Recv(&req); err != nil { if err != io.EOF { log.Warningf("Server side recv: %v", err) } return false } log.Debugf("Got request: %v", req) fn, ok := lay.handlers[req.ReqType] if !ok { log.Warningf("Received packet without registerd handler (%d)", req.ReqType) log.Warningf("Package will be dropped.") return true } resp, err := fn(&req) if err != nil { resp = &wire.Response{ Error: err.Error(), } } if resp == nil { // '0' is the ID for broadcast. Empty response are valid there. if req.ID != 0 { log.Warningf("Handle for `%d` failed to return a response or error", req.ReqType) } return true } // Auto-fill the type and ID fields from the response: resp.ReqType = req.ReqType resp.ID = req.ID resp.Nonce = req.Nonce log.Debugf("Sending back %v", resp) if err := prot.Send(resp); err != nil { log.Warningf("Unable to send back response: %v", err) return false } return true }