En el anterior post creamos una aplicación tipo cliente-servidor con gRPC.
La clase tipo "service" que creamos funciona parcialmente. Sin embargo, requiere ciertos ajustes.
PalindromaServiceImpl.java
package com.inforhomex.grpc; import com.inforhomex.grpc.PalindromaProto.PalabraResponse; import com.inforhomex.grpc.PalindromaProto.PalabraRequest; import io.grpc.stub.StreamObserver; public class PalindromaServiceImpl extends PalindromaServiceGrpc.PalindromaServiceImplBase { @Override public void evaluaCadena(PalabraRequest request, StreamObserver<PalabraResponse> responseObserver) { String cadena = request.getCadena(); String invertida = new StringBuilder(cadena).reverse().toString(); String respuesta; if (cadena.equalsIgnoreCase(invertida)) { respuesta = "La cadena '" + cadena + "' es un palíndromo."; } else { respuesta = "La cadena '" + cadena + "' NO es un palíndromo."; } PalabraResponse response = PalabraResponse.newBuilder() .setRespuesta(respuesta) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } }
El método evaluaCadena funcionó para la cadena "bob", pero para la cadena "anita lava la tina" falló. Por lo cual es necesario reescribir el código.
Además también modificaremos el código del cliente para que permita escribir cadenas y no tenerla seteada.
PalindromaClient.java
package com.inforhomex.grpc; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import com.inforhomex.grpc.PalindromaProto.PalabraResponse; import com.inforhomex.grpc.PalindromaProto.PalabraRequest; public class PalindromaClient { public static void main(String[] args) { ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051) .usePlaintext() .build(); PalindromaServiceGrpc.PalindromaServiceBlockingStub stub = PalindromaServiceGrpc.newBlockingStub(channel); PalabraRequest request = PalabraRequest.newBuilder() .setCadena("bob") .build(); PalabraResponse response = stub.evaluaCadena(request); System.out.println("Respuesta del servidor: " + response.getRespuesta()); channel.shutdown(); } }
Comencemos entonces.
Mejorando el servicio
Modificaremos el método que evalúa si la cadena es o no una palíndroma.
@Override public void evaluaCadena(PalabraRequest request, StreamObserver<PalabraResponse> responseObserver) { String cadena = request.getCadena(); String respuesta = null; String original = cadena; String limpia = Normalizer.normalize(original, Normalizer.Form.NFD) .replaceAll("\\p{M}", "") .replaceAll("\\s+", "") .toLowerCase(); String temp = ""; for (int i = limpia.length() - 1; i >= 0; i--) { temp = temp + limpia.charAt(i); } if (temp.equals(limpia)) { respuesta = "La cadena '" + original + "' es un palíndromo."; } else { respuesta = "La cadena '" + original + "' NO es un palíndromo."; } PalabraResponse response = PalabraResponse.newBuilder() .setRespuesta(respuesta) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); }
El método toma la cadena y la limpiará de caracteres tipo coma, acentos y espacios en blanco. Almacenará el valor de la cadena en la variable temporal (temp). Recorrerá la cadena temp y al final evaluará si es igual o no a la cadena original.
Código completo:
package com.inforhomex.grpc; import com.inforhomex.grpc.PalindromaProto.PalabraResponse; import com.inforhomex.grpc.PalindromaProto.PalabraRequest; import io.grpc.stub.StreamObserver; import java.text.Normalizer; public class PalindromaServiceImpl extends PalindromaServiceGrpc.PalindromaServiceImplBase { @Override public void evaluaCadena(PalabraRequest request, StreamObserver<PalabraResponse> responseObserver) { String cadena = request.getCadena(); String respuesta = null; String original = cadena; String limpia = Normalizer.normalize(original, Normalizer.Form.NFD) .replaceAll("\\p{M}", "") .replaceAll("\\s+", "") .toLowerCase(); String temp = ""; for (int i = limpia.length() - 1; i >= 0; i--) { temp = temp + limpia.charAt(i); } if (temp.equals(limpia)) { respuesta = "La cadena '" + original + "' es un palíndromo."; } else { respuesta = "La cadena '" + original + "' NO es un palíndromo."; } PalabraResponse response = PalabraResponse.newBuilder() .setRespuesta(respuesta) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } }
Con esto ya no habrá el error presentado en el anterior código.
Ahora modificaremos el cliente. De tal manera permita que el usuario introduzca una cadena a evaluar. Además solicitará si desea continuar o no. Haciendo más iteractiva la acción.
package com.inforhomex.grpc; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import com.inforhomex.grpc.PalindromaProto.PalabraResponse; import com.inforhomex.grpc.PalindromaProto.PalabraRequest; import java.util.Scanner; public class PalindromaClient { public static void main(String[] args) { ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051) .usePlaintext() .build(); PalindromaServiceGrpc.PalindromaServiceBlockingStub stub = PalindromaServiceGrpc.newBlockingStub(channel); Scanner scanner = new Scanner(System.in); String opcion; do { System.out.print("Introduce una cadena: "); String cadena = scanner.nextLine(); PalabraRequest request = PalabraRequest.newBuilder() .setCadena(cadena) .build(); PalabraResponse response = stub.evaluaCadena(request); System.out.println("Respuesta del servidor: " + response.getRespuesta()); System.out.print("\nDesea continuar? [s-n]: "); opcion = scanner.nextLine().trim().toLowerCase(); } while (opcion.equals("s")); System.out.println("\nAdios."); scanner.close(); channel.shutdown(); } }
Tendremos que limpiar y compilar de nuevo:
$ mvn clean compile
Lanzamos el servidor:
$ mvn exec:java@run-server
Salida:
Servidor gRPC iniciado en el puerto 50051
Lanzamos el cliente:
$ mvn exec:java@run-client
Salida:
Introduce una cadena: anita lava la tina Respuesta del servidor: La cadena 'anita lava la tina' es un palíndromo. Desea continuar? [s-n]: s Introduce una cadena: tenet Respuesta del servidor: La cadena 'tenet' es un palíndromo. Desea continuar? [s-n]: s Introduce una cadena: tom Respuesta del servidor: La cadena 'tom' NO es un palíndromo. Desea continuar? [s-n]: n Adios.
¡Hemos mejorado nuestra aplicación!
Continuaremos con estos temas en próximas entregas.
Enlaces:
https://grpcurl.com/https://grpc.io/
https://protobuf.dev/
https://emanuelpeg.blogspot.com/2024/01/que-es-grpc.html
https://alquimistadecodigo.blogspot.com/2024/05/grpc-protobuff-protocol-buffers.html


Comentarios
Publicar un comentario