maked car control client

This commit is contained in:
MaximZaitsev
2016-07-14 12:39:06 +03:00
parent 32e30f6833
commit e6025f6bcb
7 changed files with 1951 additions and 0 deletions
+22
View File
@@ -17,11 +17,33 @@ apply plugin: 'kotlin'
sourceCompatibility = 1.5
task getDeps(type: Copy) {
from sourceSets.main.compileClasspath
into 'build/libs'
}
build.dependsOn getDeps
repositories {
mavenCentral()
}
jar {
manifest {
attributes("Implementation-Title": "Gradle",
"Implementation-Version": version,
"Class-Path": "jsap-2.1.jar kotlin-runtime-1.0.3.jar kotlin-stdlib-1.0.3.jar netty-all-4.1.2.Final.jar protobuf-java-3.0.0-beta-3.jar",
"Main-Class": "MainKt")
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "io.netty:netty-all:4.1.2.Final"
compile "com.google.protobuf:protobuf-java:3.0.0-beta-3"
compile group: "com.martiansoftware",name:"jsap",version:"2.1"
testCompile group: 'junit', name: 'junit', version: '4.11'
}
@@ -0,0 +1,50 @@
import io.netty.buffer.Unpooled
import io.netty.handler.codec.http.*
import proto.car.RouteP
import proto.car.RouteP.Direction.Command
/**
* Created by user on 7/14/16.
*/
class CarControl constructor(host: String, port: Int) {
val host: String;
val port: Int
init {
this.host = host;
this.port = port;
}
fun executeCommand(direction: Char) {
val directionBuilder = RouteP.Direction.newBuilder()
when (direction) {
'f' -> {
directionBuilder.setCommand(Command.forward)
}
'b' -> {
directionBuilder.setCommand(Command.backward)
}
'r' -> {
directionBuilder.setCommand(Command.right)
}
'l' -> {
directionBuilder.setCommand(Command.left)
}
's' -> {
directionBuilder.setCommand(Command.stop)
}
}
val request = DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/control", Unpooled.copiedBuffer(directionBuilder.build().toByteArray()));
request.headers().set(HttpHeaderNames.HOST, host)
request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
request.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes())
request.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8")
client.Client.sendRequest(request, host, port)
}
}
@@ -1,3 +1,68 @@
import com.martiansoftware.jsap.FlaggedOption
import com.martiansoftware.jsap.JSAP
import java.util.*
/**
* Created by user on 7/14/16.
*/
val correctDirectionValues: Array<Char> = arrayOf('f', 'b', 'l', 'r', 's');
fun main(args: Array<String>) {
val jsap: JSAP = JSAP()
setOptions(jsap)
val config = jsap.parse(args)
if (!config.success() || config.getBoolean("help")) {
println(jsap.getHelp())
return
}
val host = config.getString("host")
val port = config.getInt("port")
val direction = config.getChar("direction")
val carControl = CarControl(host, port)
if (direction.equals('t', true)) {
initTextInterface(carControl)
} else if (correctDirectionValues.contains(direction)) {
carControl.executeCommand(direction)
} else {
println("incorrect direction.")
println(jsap.getHelp())
}
}
fun initTextInterface(carControl: CarControl) {
val helpMessage = "type f, b, l, r, s for command forward, backward, left, right, stop. to exit type q or quit ";
println(helpMessage)
val scanner = Scanner(System.`in`)
while (scanner.hasNext()) {
val nextLine = scanner.nextLine()
if (nextLine.equals("q", true) || nextLine.equals("quit", true)) {
return
} else if (nextLine.length != 1) {
println("incorrect argument \"$nextLine\"")
println(helpMessage)
} else {
val directionChar = nextLine.get(0)
if (!correctDirectionValues.contains(directionChar)) {
println("incorrect argument \"$nextLine\"")
println(helpMessage)
} else {
carControl.executeCommand(directionChar)
}
}
}
}
fun setOptions(jsap: JSAP) {
val opthost = FlaggedOption("host").setStringParser(JSAP.STRING_PARSER).setRequired(true).setShortFlag('h').setLongFlag("host")
val optPort = FlaggedOption("port").setStringParser(JSAP.INTEGER_PARSER).setDefault("8888").setRequired(false).setShortFlag('p').setLongFlag("port")
val optHelp = FlaggedOption("help").setStringParser(JSAP.BOOLEAN_PARSER).setRequired(false).setDefault("false").setLongFlag("help")
val optDirection = FlaggedOption("direction").setStringParser(JSAP.CHARACTER_PARSER).setRequired(false).setDefault("t").setShortFlag('d')
optDirection.setHelp("move direction: available values - one symbol:\n\"f (forward),b (backward),l (left),r (right),s (stop)\". example: -d f\nwithout argument used default \"t\" - running text interface")
jsap.registerParameter(opthost)
jsap.registerParameter(optPort)
jsap.registerParameter(optHelp)
jsap.registerParameter(optDirection)
}
@@ -0,0 +1,35 @@
package client
import io.netty.bootstrap.Bootstrap
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.handler.codec.http.HttpRequest
import java.net.ConnectException
/**
* Created by user on 7/8/16.
*/
object Client {
fun sendRequest(request: HttpRequest, host: String, port: Int): Int {
val group = NioEventLoopGroup()
try {
val bootstrap: Bootstrap = Bootstrap()
bootstrap.group(group).channel(NioSocketChannel().javaClass).handler(ClientInitializer())
val channelFuture = bootstrap.connect(host, port).sync()
val channel = channelFuture.channel()
channel.writeAndFlush(request)
channel.closeFuture().sync()
} catch (e: InterruptedException) {
println("interrupted before request done")
return 2
} catch (e: ConnectException) {
println("connection error to $host:$port")
return 1
} finally {
group.shutdownGracefully()
}
return ClientHandler.requestResult.code
}
}
@@ -0,0 +1,51 @@
package client
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.handler.codec.http.HttpContent
/**
* Created by user on 7/8/16.
*/
class ClientHandler : SimpleChannelInboundHandler<Any> {
object requestResult {
var code: Int = -1
}
constructor()
var contentBytes: ByteArray = ByteArray(0);
override fun channelReadComplete(ctx: ChannelHandlerContext) {
var resultCode: Int = 0
// try {
// val uploadResult: Carkot.UploadResult = Carkot.UploadResult.parseFrom(contentBytes)
// resultCode = uploadResult.resultCode
// } catch (e: InvalidProtocolBufferException) {
// e.printStackTrace()
//
// resultCode = 2
// }
synchronized(requestResult, {
requestResult.code = resultCode
})
ctx.close()
}
override fun channelRead0(ctx: ChannelHandlerContext?, msg: Any?) {
if (msg is HttpContent) {
val contentsBytes = msg.content();
contentBytes = ByteArray(contentsBytes.capacity())
contentsBytes.readBytes(contentBytes)
}
}
override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable) {
cause.printStackTrace()
if (ctx != null) {
ctx.close()
}
}
}
@@ -0,0 +1,19 @@
package client
import io.netty.channel.ChannelInitializer
import io.netty.channel.socket.SocketChannel
import io.netty.handler.codec.http.HttpClientCodec
/**
* Created by user on 7/8/16.
*/
class ClientInitializer : ChannelInitializer<SocketChannel> {
constructor()
override fun initChannel(ch: SocketChannel) {
val p = ch.pipeline()
p.addLast(HttpClientCodec())
p.addLast(ClientHandler())
}
}
File diff suppressed because it is too large Load Diff