maked car control client
This commit is contained in:
@@ -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
Reference in New Issue
Block a user