Java tutorial
/* * Copyright 2014 The Netty Project * * The Netty Project licenses this file to you under the Apache License, version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package push2.apns.demo2; import static io.netty.buffer.Unpooled.wrappedBuffer; import static io.netty.handler.codec.http.HttpMethod.POST; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; import com.training.push.apns.JWT; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpScheme; import io.netty.handler.codec.http2.Http2SecurityUtil; import io.netty.handler.codec.http2.HttpConversionUtil; import io.netty.handler.ssl.ApplicationProtocolConfig; import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol; import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior; import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; import io.netty.handler.ssl.ApplicationProtocolNames; import io.netty.handler.ssl.OpenSsl; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; import io.netty.handler.ssl.SupportedCipherSuiteFilter; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import io.netty.util.AsciiString; import io.netty.util.CharsetUtil; import java.util.concurrent.TimeUnit; /** * An HTTP2 client that allows you to send HTTP2 frames to a server. Inbound and outbound frames are * logged. When run from the command-line, sends a single HEADERS frame to the server and gets back * a "Hello World" response. */ public final class Http2Client { private static final String HOST = "api.push.apple.com"; private static final int PORT = 443; private static final String TEAM_ID = "4S5ZWGJSPN"; private static final String KEY_ID = "CPPMHRM7CC"; private static final String ACCESS_SECRET = "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgjZTdQgZM/8AQspuD9G7aTsQTEBqomiu4TJ0LxU5gaI+gCgYIKoZIzj0DAQehRANCAASbKaMLxR56q2N0oQ8YXcOFEhHL7cAuNcLUwkMTLplUKoaRzSY9Me85UnjtuMxjmYpFkbmYtFtrNULzedlBXk/K"; private static final String DEVICE_TOKEN = "82697704db71dd64f9d42365c440e6f53afa858a5467e017fbda5377406a3203"; private static final String payload = "{\n" + " \"aps\" : { \"alert\" : \"Hello World\" },\n" + " \"acme2\" : [ \"bang\", \"whiz\" ]\n" + "}"; public static void main(String[] args) throws Exception { // Configure SSL. final SslContext sslCtx; SslProvider provider = OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK; sslCtx = SslContextBuilder.forClient().sslProvider(provider) /* NOTE: the cipher filter may not include all ciphers required by the HTTP/2 specification. * Please refer to the HTTP/2 specification for cipher requirements. */ .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE) .trustManager(InsecureTrustManagerFactory.INSTANCE) .applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN, // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers. SelectorFailureBehavior.NO_ADVERTISE, // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers. SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)) .build(); EventLoopGroup workerGroup = new NioEventLoopGroup(); Http2ClientInitializer initializer = new Http2ClientInitializer(sslCtx, Integer.MAX_VALUE); try { // Configure the client. Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class); b.option(ChannelOption.SO_KEEPALIVE, true); b.remoteAddress(HOST, PORT); b.handler(initializer); // Start the client. Channel channel = b.connect().channel(); System.out.println("Connected to [" + HOST + ':' + PORT + ']'); // Wait for the HTTP/2 upgrade to occur. Http2SettingsHandler http2SettingsHandler = initializer.settingsHandler(); //http2SettingsHandler.awaitSettings(5, TimeUnit.SECONDS); HttpResponseHandler responseHandler = initializer.responseHandler(); int streamId = 3; AsciiString hostName = new AsciiString(HOST + ':' + PORT); System.err.println("Sending request(s)..."); // Create a simple POST request with a body. FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, "https://" + HOST + "/3/device/" + DEVICE_TOKEN, wrappedBuffer(payload.getBytes(CharsetUtil.UTF_8))); request.headers().add(HttpHeaderNames.HOST, hostName); request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), HttpScheme.HTTPS.name()); request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP); request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.DEFLATE); request.headers().add("authorization", "bearer " + JWT.getToken(TEAM_ID, KEY_ID, ACCESS_SECRET)); request.headers().add("apns-topic", "com.hujiang.hjm.normandy"); channel.write(request); // responseHandler.put(streamId, channel.write(request), channel.newPromise()); channel.flush(); //responseHandler.awaitResponses(5, TimeUnit.SECONDS); System.out.println("Finished HTTP/2 request(s)"); // Wait until the connection is closed. channel.close().syncUninterruptibly(); } finally { workerGroup.shutdownGracefully(); } while (Thread.activeCount() > 1) { Thread.yield(); } } }