// this function is the goroutine that owns this service - all thread-sensitive data needs to // be manipulated only through here. func (s *Service) mux() { loop: for { select { case conn := <-s.connectionChan: clientID := config.NewUUID() s.clientMutex.Lock() s.ClientInfo[clientID] = ClientInfo{ Address: conn.RemoteAddr(), } s.clientMutex.Unlock() // send the server handshake sh := skynet.ServiceHandshake{ Registered: s.Registered, ClientID: clientID, Name: s.Name, } encoder := bsonrpc.NewEncoder(conn) err := encoder.Encode(sh) if err != nil { log.Println(log.ERROR, "Failed to encode server handshake", err.Error()) continue } if !s.Registered { log.Println(log.ERROR, "Connection attempted while unregistered. Closing connection") conn.Close() continue } // read the client handshake var ch skynet.ClientHandshake decoder := bsonrpc.NewDecoder(conn) err = decoder.Decode(&ch) if err != nil { log.Println(log.ERROR, "Error calling bsonrpc.NewDecoder: "+err.Error()) continue } // here do stuff with the client handshake go func() { s.RPCServ.ServeCodec(bsonrpc.NewServerCodec(conn)) }() case register := <-s.registeredChan: if register { s.register() } else { s.unregister() } case <-s.shutdownChan: s.shutdown() case _ = <-s.doneChan: break loop } } }
func doServiceHandshake(server net.Conn, registered bool, t *testing.T) { sh := skynet.ServiceHandshake{ Registered: registered, ClientID: "abc", } encoder := bsonrpc.NewEncoder(server) err := encoder.Encode(sh) if err != nil { t.Fatal("Failed to encode server handshake", err) } var ch skynet.ClientHandshake decoder := bsonrpc.NewDecoder(server) err = decoder.Decode(&ch) if err != nil { t.Fatal("Error calling bsonrpc.NewDecoder: ", err) } }
/* Conn.performHandshake Responsible for performing handshake with service */ func (c *Conn) performHandshake() (err error) { var sh skynet.ServiceHandshake decoder := bsonrpc.NewDecoder(c.conn) err = decoder.Decode(&sh) if err != nil { log.Println(log.ERROR, "Failed to decode ServiceHandshake", err) c.conn.Close() return HandshakeFailed } if sh.Name != c.serviceName { log.Println(log.ERROR, "Attempted to send request to incorrect service: "+sh.Name) return HandshakeFailed } ch := skynet.ClientHandshake{} encoder := bsonrpc.NewEncoder(c.conn) err = encoder.Encode(ch) if err != nil { log.Println(log.ERROR, "Failed to encode ClientHandshake", err) c.conn.Close() return HandshakeFailed } if !sh.Registered { log.Println(log.ERROR, "Attempted to send request to unregistered service") return ServiceUnregistered } c.rpcClient = bsonrpc.NewClient(c.conn) c.clientID = sh.ClientID return }