Examples can now be run at command line by Gradle
* Update README to reflect use of Gradle for build. * Add gradle tasks to run the NIO and Netty examples. * Ensure both examples exit quickly.
This commit is contained in:
15
README.md
15
README.md
@ -21,8 +21,17 @@ created by Adam Langley and Robert Obryk.
|
|||||||
exploring the [Nearenough API and details of Roughtime messages](https://int08h.com/post/roughtime-message-anatomy/).
|
exploring the [Nearenough API and details of Roughtime messages](https://int08h.com/post/roughtime-message-anatomy/).
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
Nearenough bundles all required dependencies in the `lib` directory. Add those `.jar` files to
|
Gradle is used to build Nearenough.
|
||||||
your IDE's project classpath. Building is IDE-only for the moment.
|
|
||||||
|
```bash
|
||||||
|
$ ./gradlew nioExample
|
||||||
|
```
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./gradlew nettyExample
|
||||||
|
```
|
||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
@ -75,7 +84,7 @@ If you would like to contribute to Nearenough, please see the guidelines in
|
|||||||
[CONTRIBUTING.md](../master/CONTRIBUTING.md).
|
[CONTRIBUTING.md](../master/CONTRIBUTING.md).
|
||||||
|
|
||||||
## Copyright and License
|
## Copyright and License
|
||||||
Nearenough is Copyright (c) 2017 int08h LLC. All rights reserved.
|
Nearenough is Copyright (c) 2017-2018 int08h LLC. All rights reserved.
|
||||||
|
|
||||||
int08h LLC licenses Nearenough (the "Software") to you under the Apache License, version 2.0
|
int08h LLC licenses Nearenough (the "Software") to you under the Apache License, version 2.0
|
||||||
(the "License"); you may not use this Software except in compliance with the License. You may obtain
|
(the "License"); you may not use this Software except in compliance with the License. You may obtain
|
||||||
|
37
build.gradle
37
build.gradle
@ -1,16 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Gradle build for Nearenough
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017-2018 int08h LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'eclipse'
|
||||||
|
apply plugin: 'idea'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// local snapshot of Ed25519
|
// local snapshot of Ed25519
|
||||||
compile files('lib/eddsa-0.1.0.jar')
|
compile files('lib/eddsa-0.1.0.jar')
|
||||||
|
|
||||||
compile 'io.netty:netty-all:4.1.16.Final'
|
compile 'io.netty:netty-all:4.1.20.Final'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suppress "Illegal reflective access" warnings on Java 9
|
||||||
|
def shouldAddOpens = JavaVersion.current().java9Compatible
|
||||||
|
|
||||||
|
// Runs the NIO example
|
||||||
|
task nioExample(type: JavaExec) {
|
||||||
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
main = 'nearenough.examples.NioClient'
|
||||||
|
|
||||||
|
if (shouldAddOpens) {
|
||||||
|
jvmArgs = ['--add-opens', 'java.base/java.nio=ALL-UNNAMED']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs the NIO example
|
||||||
|
task nettyExample(type: JavaExec) {
|
||||||
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
main = 'nearenough.examples.NettyClient'
|
||||||
|
|
||||||
|
if (shouldAddOpens) {
|
||||||
|
jvmArgs = [
|
||||||
|
'--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED',
|
||||||
|
'--add-opens', 'java.base/java.nio=ALL-UNNAMED'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
package nearenough.examples;
|
||||||
|
|
||||||
import static nearenough.util.BytesUtil.hexToBytes;
|
import static nearenough.util.BytesUtil.hexToBytes;
|
||||||
|
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
@ -26,8 +28,8 @@ import io.netty.channel.socket.DatagramPacket;
|
|||||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||||
import io.netty.handler.timeout.ReadTimeoutException;
|
import io.netty.handler.timeout.ReadTimeoutException;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import nearenough.client.RoughtimeClient;
|
import nearenough.client.RoughtimeClient;
|
||||||
import nearenough.protocol.RtMessage;
|
import nearenough.protocol.RtMessage;
|
||||||
@ -70,9 +72,9 @@ public final class NettyClient {
|
|||||||
|
|
||||||
// Sends the request to the Roughtime server
|
// Sends the request to the Roughtime server
|
||||||
ctx.writeAndFlush(new DatagramPacket(encodedMsg, addr))
|
ctx.writeAndFlush(new DatagramPacket(encodedMsg, addr))
|
||||||
.addListener(fut -> {
|
.addListener(future -> {
|
||||||
if (!fut.isSuccess()) {
|
if (!future.isSuccess()) {
|
||||||
System.out.println("Send failed " + fut.cause().getMessage());
|
System.out.println("Send failed " + future.cause().getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -114,7 +116,7 @@ public final class NettyClient {
|
|||||||
System.out.println("Response INVALID: " + client.invalidResponseCause().getMessage());
|
System.out.println("Response INVALID: " + client.invalidResponseCause().getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.close();
|
ctx.close().addListener(unused -> System.exit(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -130,16 +132,15 @@ public final class NettyClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException, NoSuchAlgorithmException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
InetSocketAddress addr = new InetSocketAddress(GOOGLE_SERVER_HOST, GOOGLE_SERVER_PORT);
|
InetSocketAddress addr = new InetSocketAddress(GOOGLE_SERVER_HOST, GOOGLE_SERVER_PORT);
|
||||||
|
|
||||||
System.out.printf("Sending request to %s\n", addr);
|
System.out.printf("Sending request to %s\n", addr);
|
||||||
|
|
||||||
// Below is Netty boilerplate for setting-up an event loop and registering a handler
|
// Below is Netty boilerplate for setting-up an event loop and registering a handler
|
||||||
|
NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
|
||||||
NioEventLoopGroup group = new NioEventLoopGroup();
|
|
||||||
Bootstrap bootstrap = new Bootstrap()
|
Bootstrap bootstrap = new Bootstrap()
|
||||||
.group(group)
|
.group(nioEventLoopGroup)
|
||||||
.remoteAddress(addr)
|
.remoteAddress(addr)
|
||||||
.channel(NioDatagramChannel.class)
|
.channel(NioDatagramChannel.class)
|
||||||
.handler(new ChannelInitializer<NioDatagramChannel>() {
|
.handler(new ChannelInitializer<NioDatagramChannel>() {
|
||||||
@ -152,14 +153,14 @@ public final class NettyClient {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ChannelFuture connectFuture = bootstrap.connect();
|
ChannelFuture connectFuture = bootstrap.connect();
|
||||||
connectFuture.addListener(fut -> {
|
connectFuture.addListener(future -> {
|
||||||
if (!fut.isSuccess()) {
|
if (!future.isSuccess()) {
|
||||||
System.out.println("Connect fail:");
|
System.out.println("Connect fail:");
|
||||||
System.out.println(fut.cause().getMessage());
|
System.out.println(future.cause().getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connectFuture.channel().closeFuture().sync();
|
connectFuture.channel().closeFuture().sync();
|
||||||
group.shutdownGracefully();
|
nioEventLoopGroup.shutdownGracefully();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,10 +12,12 @@
|
|||||||
* either express or implied. See the License for the specific language governing permissions and
|
* either express or implied. See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
package nearenough.examples;
|
||||||
|
|
||||||
import static nearenough.util.BytesUtil.hexToBytes;
|
import static nearenough.util.BytesUtil.hexToBytes;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.StandardProtocolFamily;
|
import java.net.StandardProtocolFamily;
|
||||||
@ -48,7 +50,6 @@ public final class NioClient {
|
|||||||
// Nonblocking NIO UDP channel for the remote Roughtime server
|
// Nonblocking NIO UDP channel for the remote Roughtime server
|
||||||
DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);
|
DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);
|
||||||
channel.configureBlocking(false);
|
channel.configureBlocking(false);
|
||||||
channel.socket().bind(new InetSocketAddress(GOOGLE_SERVER_PORT));
|
|
||||||
|
|
||||||
// Create a new RoughtimeClient instance
|
// Create a new RoughtimeClient instance
|
||||||
RoughtimeClient client = new RoughtimeClient(GOOGLE_SERVER_PUBKEY);
|
RoughtimeClient client = new RoughtimeClient(GOOGLE_SERVER_PUBKEY);
|
||||||
@ -59,7 +60,8 @@ public final class NioClient {
|
|||||||
// Encode for transmission
|
// Encode for transmission
|
||||||
ByteBuf encodedRequest = RtWire.toWire(request);
|
ByteBuf encodedRequest = RtWire.toWire(request);
|
||||||
|
|
||||||
// Send the encoded request, converting the Netty ByteBuf to a Java ByteBuffer for NIO use.
|
// Send the message
|
||||||
|
channel.send(encodedRequest.nioBuffer(), addr);
|
||||||
int bytesWritten = channel.send(encodedRequest.nioBuffer(), addr);
|
int bytesWritten = channel.send(encodedRequest.nioBuffer(), addr);
|
||||||
|
|
||||||
// Ensure the message was sent
|
// Ensure the message was sent
|
||||||
@ -118,5 +120,7 @@ public final class NioClient {
|
|||||||
// No reply within five seconds
|
// No reply within five seconds
|
||||||
System.out.println("No response from " + addr);
|
System.out.println("No response from " + addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user