2017-10-12 216 views
0

我試圖ping一個grpc http2服務器端口的活躍性。在Http1.1中,我們將使用url.openConnection並檢查響應狀態碼。如何ping http2服務器端口的活性(grpc服務器)?

http2中的等價物是什麼?

下面的代碼似乎沒有錯誤,但我不能完全告訴如何使用它來檢查請求是否成功?

import org.apache.commons.io.IOUtils; 
import org.eclipse.jetty.http.HttpFields; 
import org.eclipse.jetty.http.HttpURI; 
import org.eclipse.jetty.http.HttpVersion; 
import org.eclipse.jetty.http.MetaData; 
import org.eclipse.jetty.http2.api.Session; 
import org.eclipse.jetty.http2.api.Stream; 
import org.eclipse.jetty.http2.api.server.ServerSessionListener; 
import org.eclipse.jetty.http2.client.HTTP2Client; 
import org.eclipse.jetty.http2.frames.DataFrame; 
import org.eclipse.jetty.http2.frames.HeadersFrame; 
import org.eclipse.jetty.util.Callback; 
import org.eclipse.jetty.util.FuturePromise; 
import org.eclipse.jetty.util.Jetty; 
import org.eclipse.jetty.util.ssl.SslContextFactory; 

import javax.net.ssl.HttpsURLConnection; 
import java.io.IOException; 
import java.net.HttpURLConnection; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.URL; 
import java.util.concurrent.TimeUnit; 

public class HeartbeatCheckHttp2 { 
    public static void main(String [] args) throws Exception { 
     for (int i=0; i<50000; ++i) { 
      Thread.sleep(400L); 

      HTTP2Client client = new HTTP2Client(); 
      client.start(); 

      // Connect to host. 
      String host = "localhost"; 
      int port = 50000; 

      FuturePromise<Session> sessionPromise = new FuturePromise<>(); 
      client.connect(new InetSocketAddress(host, port), new ServerSessionListener.Adapter(), sessionPromise); 


      // Obtain the client Session object. 
      Session session = sessionPromise.get(5, TimeUnit.SECONDS); 

      // Prepare the HTTP request headers. 
      HttpFields requestFields = new HttpFields(); 
      requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION); 
      requestFields.put("Content-Type", "application/grpc"); 
      // Prepare the HTTP request object. 
      MetaData.Request request = new MetaData.Request("POST", new HttpURI("http://" + host + ":" + port + "/"), HttpVersion.HTTP_2, requestFields); 
      // Create the HTTP/2 HEADERS frame representing the HTTP request. 
      HeadersFrame headersFrame = new HeadersFrame(request, null, true); 

      // Prepare the listener to receive the HTTP response frames. 
      Stream.Listener responseListener = new Stream.Listener.Adapter() 
      { 
       @Override 
       public void onData(Stream stream, DataFrame frame, Callback callback) 
       { 
        byte[] bytes = new byte[frame.getData().remaining()]; 
        frame.getData().get(bytes); 
        callback.succeeded(); 
       } 
      }; 

      session.newStream(headersFrame, new FuturePromise<>(), responseListener); 
      session.newStream(headersFrame, new FuturePromise<>(), responseListener); 
      session.newStream(headersFrame, new FuturePromise<>(), responseListener); 

      Thread.sleep(TimeUnit.SECONDS.toMillis(20)); 


      client.stop(); 
     } 
    } 
} 

我可以使用的SocketAddress ping通了TCP活躍度,但我想打一個實際Http2調用來完成活躍度檢查。

回答

1

HTTP/2協議具有內置的心跳幀,可用於「ping」另一個節點的活躍度。

HTTP2Client client = new HTTP2Client(); 
client.start(); 

FuturePromise<Session> sessionPromise = new FuturePromise<>(); 
client.connect(new InetSocketAddress(host, port), new ServerSessionListener.Adapter() { 
    @Override 
    public void onPing(Session session, PingFrame frame) { 
     // The other peer replies to our pings. 
    } 
}, sessionPromise); 
Session session = sessionPromise.get(5, TimeUnit.SECONDS); 

session.ping(new PingFrame(System.nanoTime(), false), Callback.NOOP); 

說到關於內置平設施,如果要檢查HTTP請求的響應狀態,你應該實現onHeaders()

Stream.Listener responseListener = new Stream.Listener.Adapter() { 
    @Override 
    public void onHeaders(Stream stream, HeadersFrame frame) { 
     MetaData metaData = frame.getMetaData(); 
     if (metaData.isResponse()) { 
      MetaData.Response response = (MetaData.Response)metaData; 
      int status = response.getStatus(); 
      ... 
     } 
    } 

    @Override 
    public void onData(Stream stream, DataFrame frame, Callback callback) { 
     ... 
    } 
}; 

這是你將如何與做一個通過HTTP/2成幀來講HTTP的服務器。

對於gRPC,情況可能不同,因爲gRPC protocol是通過HTTP/2幀傳輸的,但它不是HTTP。