ballerina 学习二十一 http2

ballerina 支持http2 协议,包含server push

http2 协议

  • 参考代码
import ballerina/http;
import ballerina/log;endpoint http:Client http2serviceClientEP {
    url: "http://localhost:7090",
    httpVersion: "2.0"};@http:ServiceConfig {
    basePath: "/http11Service"
}
service<http:Service> http11Service bind { port: 9090 } { @http:ResourceConfig {
        path: "/"
    }
    http11Resource(endpoint caller, http:Request clientRequest) {
        var clientResponse =
            http2serviceClientEP->forward("/http2service", clientRequest); http:Response response = new;
        match clientResponse {
            http:Response resultantResponse => {
                response = resultantResponse;
            }
            error err => {
                response.statusCode = 500;
                response.setPayload(err.message); }
        }
        caller->respond(response) but {
            error e => log:printError(
                           "Error occurred while sending the response",
                           err = e) }; }
}endpoint http:Listener http2serviceEP {
    port: 7090,
    httpVersion: "2.0"};@http:ServiceConfig {
    basePath: "/http2service"
}
service http2service bind http2serviceEP { @http:ResourceConfig {
        path: "/"
    }
    http2Resource(endpoint caller, http:Request clientRequest) {
        http:Response response = new;
        json msg = { "response": { "message": "response from http2 service" } };
        response.setPayload(msg);
        caller->respond(response) but {
            error e => log:printError(
                           "Error occurred while sending the response",
                           err = e) }; }
}

server push

  • 参考代码
import ballerina/http;
import ballerina/log;
endpoint http:Listener http2ServiceEP {
    port: 7090,
    httpVersion: "2.0"};@http:ServiceConfig {
    basePath: "/http2Service"
}
service http2Service bind http2ServiceEP { @http:ResourceConfig {
        path: "/"
    }
    http2Resource(endpoint caller, http:Request req) {
        http:PushPromise promise1 = new(path = "/resource1", method = "GET");
        caller->promise(promise1) but {
            error e => log:printError(
                           "Error occurred while sending the promise1",
                           err = e) };
        http:PushPromise promise2 = new(path = "/resource2", method = "GET");
        caller->promise(promise2) but {
            error e => log:printError(
                           "Error occurred while sending the promise2",
                           err = e) };
        http:PushPromise promise3 = new(path = "/resource3", method = "GET");
        caller->promise(promise3) but {
            error e => log:printError(
                           "Error occurred while sending the promise3",
                           err = e) };
        http:Response response = new;
        json msg = { "response": { "name": "main resource" } };
        response.setPayload(msg);
        caller->respond(response) but {
            error e => log:printError(
                           "Error occurred while sending the response",
                           err = e) };
        http:Response push1 = new;
        msg = { "push": { "name": "resource1" } };
        push1.setPayload(msg);
        caller->pushPromisedResponse(promise1, push1) but {
            error e => log:printError(
                           "Error occurred while sending the promised response1",
                           err = e) };
        http:Response push2 = new;
        msg = { "push": { "name": "resource2" } };
        push2.setPayload(msg);
        caller->pushPromisedResponse(promise2, push2) but {
            error e => log:printError(
                           "Error occurred while sending the promised response2",
                           err = e) };
        http:Response push3 = new;
        msg = { "push": { "name": "resource3" } };
        push3.setPayload(msg);
        caller->pushPromisedResponse(promise3, push3) but {
            error e => log:printError(
                           "Error occurred while sending the promised response3",
                           err = e) }; }
}
import ballerina/http;
import ballerina/log;
endpoint http:Client clientEP {
    url: "http://localhost:7090",
    httpVersion: "2.0"};function main(string... args) { http:Request serviceReq = new;
    http:HttpFuture httpFuture = new;
    var submissionResult = clientEP->submit("GET", "/http2Service", serviceReq); match submissionResult {
        http:HttpFuture resultantFuture => {
            httpFuture = resultantFuture;
        }
        error resultantErr => {
            log:printError("Error occurred while submitting a request",
                            err = resultantErr);
            return;
        }
    } 
 http:PushPromise[] promises = [];
    int promiseCount = 0;
    boolean hasPromise = clientEP->hasPromise(httpFuture); while (hasPromise) {
        http:PushPromise pushPromise = new;
        var nextPromiseResult = clientEP->getNextPromise(httpFuture); match nextPromiseResult {
            http:PushPromise resultantPushPromise => {
                pushPromise = resultantPushPromise;
            }
            error resultantErr => {
                log:printError("Error occurred while fetching a push promise",
                                err = resultantErr);
                return;
            }
        }
        log:printInfo("Received a promise for " + pushPromise.path); if (pushPromise.path == "/resource2") {
            clientEP->rejectPromise(pushPromise); log:printInfo("Push promise for resource2 rejected");
        } else {
            promises[promiseCount] = pushPromise; promiseCount = promiseCount + 1;
        }
        hasPromise = clientEP->hasPromise(httpFuture);
    } http:Response response = new;
    var result = clientEP->getResponse(httpFuture); match result {
        http:Response resultantResponse => {
            response = resultantResponse;
        }
        error resultantErr => {
            log:printError("Error occurred while fetching response",
                            err = resultantErr);
            return;
        }
    } var responsePayload = response.getJsonPayload();
    match responsePayload {
        json resultantJsonPayload =>
              log:printInfo("Response : " + resultantJsonPayload.toString());
        error e =>
              log:printError("Expected response payload not received", err = e);
    }
    foreach promise in promises {
        http:Response promisedResponse = new;
        var promisedResponseResult = clientEP->getPromisedResponse(promise);
        match promisedResponseResult {
            http:Response resultantPromisedResponse => {
                promisedResponse = resultantPromisedResponse;
            }
            error resultantErr => {
                log:printError("Error occurred while fetching promised response",
                                err = resultantErr);
                return;
            }
        }
        var promisedPayload = promisedResponse.getJsonPayload();
        match promisedPayload {
            json promisedJsonPayload =>
                       log:printInfo("Promised resource : " +
                                      promisedJsonPayload.toString());
            error e =>
                  log:printError("Expected promised response payload not received",
                                  err = e);
        }
    }}

参考资料

https://ballerina.io/learn/by-example/http-2.0-server-push.html
https://ballerina.io/learn/by-example/http-1.1-to-2.0-protocol-switch.html

posted on 2018-06-01 21:52  荣锋亮  阅读(171)  评论(0编辑  收藏  举报

导航