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