1 /* 2 * Copyright 2023 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.examples.keepalive; 18 19 import io.grpc.Channel; 20 import io.grpc.Grpc; 21 import io.grpc.InsecureChannelCredentials; 22 import io.grpc.ManagedChannel; 23 import io.grpc.StatusRuntimeException; 24 import io.grpc.examples.helloworld.GreeterGrpc; 25 import io.grpc.examples.helloworld.HelloReply; 26 import io.grpc.examples.helloworld.HelloRequest; 27 import java.util.concurrent.TimeUnit; 28 import java.util.logging.Level; 29 import java.util.logging.Logger; 30 31 /** 32 * A simple client that requests a greeting from the {@link KeepAliveServer}. 33 */ 34 public class KeepAliveClient { 35 private static final Logger logger = Logger.getLogger(KeepAliveClient.class.getName()); 36 37 private final GreeterGrpc.GreeterBlockingStub blockingStub; 38 39 /** Construct client for accessing HelloWorld server using the existing channel. */ KeepAliveClient(Channel channel)40 public KeepAliveClient(Channel channel) { 41 // 'channel' here is a Channel, not a ManagedChannel, so it is not this code's responsibility to 42 // shut it down. 43 44 // Passing Channels to code makes code easier to test and makes it easier to reuse Channels. 45 blockingStub = GreeterGrpc.newBlockingStub(channel); 46 } 47 48 /** Say hello to server. */ greet(String name)49 public void greet(String name) { 50 logger.info("Will try to greet " + name + " ..."); 51 HelloRequest request = HelloRequest.newBuilder().setName(name).build(); 52 HelloReply response; 53 try { 54 response = blockingStub.sayHello(request); 55 } catch (StatusRuntimeException e) { 56 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); 57 return; 58 } 59 logger.info("Greeting: " + response.getMessage()); 60 } 61 62 /** 63 * Greet server. 64 */ main(String[] args)65 public static void main(String[] args) throws Exception { 66 // Access a service running on the local machine on port 50051 67 String target = "localhost:50051"; 68 69 // Create a channel with the following keep alive configurations (demo only, you should set 70 // more appropriate values based on your environment): 71 // keepAliveTime: Send pings every 10 seconds if there is no activity. Set to an appropriate 72 // value in reality, e.g. (5, TimeUnit.MINUTES). 73 // keepAliveTimeout: Wait 1 second for ping ack before considering the connection dead. Set to a 74 // larger value in reality, e.g. (10, TimeUnit.SECONDS). You should only set such a small value, 75 // e.g. (1, TimeUnit.SECONDS) in certain low latency environments. 76 // keepAliveWithoutCalls: Send pings even without active streams. Normally disable it. 77 // Use JAVA_OPTS=-Djava.util.logging.config.file=logging.properties to see the keep alive ping 78 // frames. 79 // More details see: https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md 80 ManagedChannel channel = Grpc.newChannelBuilder(target, InsecureChannelCredentials.create()) 81 .keepAliveTime(5, TimeUnit.MINUTES) 82 .keepAliveTime(10, TimeUnit.SECONDS) // Change to a larger value, e.g. 5min. 83 .keepAliveTimeout(1, TimeUnit.SECONDS) // Change to a larger value, e.g. 10s. 84 .keepAliveWithoutCalls(true)// You should normally avoid enabling this. 85 .build(); 86 87 try { 88 KeepAliveClient client = new KeepAliveClient(channel); 89 client.greet("Keep-alive Demo"); 90 Thread.sleep(30000); 91 } finally { 92 channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); 93 } 94 } 95 } 96