如何ping http2服务器端口的活性(grpc服务器)?

时间:2017-10-12 06:39:54

标签: java grpc http2

我正在尝试ping一个grpc http2服务器端口以获得活跃性。在Http1.1中,我们将使用url.openConnection并检查响应状态代码。

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 个答案:

答案 0 :(得分:1)

HTTP / 2协议具有内置的心跳帧,可以用于&#34; ping&#34;另一个同行的生活。

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);

说到内置ping设施后,如果要检查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。