Added handling of web-requests in central server
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
parent_path=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P )
|
PROTOC="../compiler/build/protoc"
|
||||||
cd "$parent_path"
|
cd "$(dirname "${BASH_SOURCE}")"
|
||||||
mkdir out -p
|
mkdir out -p
|
||||||
../compiler/build/protoc --kotlin_out="./out/" --proto_path="./server_car" ./server_car/*.proto
|
${PROTOC} --kotlin_out="./out/" --proto_path="./server_car" ./server_car/*.proto
|
||||||
|
${PROTOC} --kotlin_out="./out/" --proto_path="./server_client" ./server_client/*.proto
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
package carkot;
|
|
||||||
|
|
||||||
option java_package = "client";
|
|
||||||
option java_out_classname = "Car";
|
|
||||||
|
|
||||||
message car {
|
|
||||||
repeated string ids = 1;
|
|
||||||
}
|
|
||||||
@@ -11,8 +11,5 @@ message DirectionRequest {
|
|||||||
}
|
}
|
||||||
Command command = 1;
|
Command command = 1;
|
||||||
int32 sid = 2;
|
int32 sid = 2;
|
||||||
}
|
bool stop = 3;
|
||||||
|
|
||||||
message DirectionResponse {
|
|
||||||
int32 code = 1;
|
|
||||||
}
|
}
|
||||||
Generated
+2
-2
@@ -20,8 +20,6 @@
|
|||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.3" level="project" />
|
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.3" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.3" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: io.netty:netty-all:4.1.2.Final" level="project" />
|
|
||||||
<orderEntry type="module-library">
|
<orderEntry type="module-library">
|
||||||
<library name="Gradle: protokot-runtime">
|
<library name="Gradle: protokot-runtime">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
@@ -31,5 +29,7 @@
|
|||||||
<SOURCES />
|
<SOURCES />
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</orderEntry>
|
||||||
|
<orderEntry type="library" name="Gradle: io.netty:netty-all:4.1.2.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.3" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
package algorithm
|
package algorithm
|
||||||
|
import Waypoints
|
||||||
/**
|
/**
|
||||||
* Created by user on 8/23/16.
|
* Created by user on 8/23/16.
|
||||||
*/
|
*/
|
||||||
@@ -7,4 +7,34 @@ object RoomModel {
|
|||||||
|
|
||||||
val point = arrayListOf<Pair<Int, Int>>()
|
val point = arrayListOf<Pair<Int, Int>>()
|
||||||
|
|
||||||
|
|
||||||
|
// DEBUG BELOW
|
||||||
|
val rng = java.util.Random(42)
|
||||||
|
var iter = 0
|
||||||
|
var currentPosition_x = 0
|
||||||
|
var currentPosition_y = 0
|
||||||
|
fun getUpdate(): Waypoints {
|
||||||
|
if (iter == 5) {
|
||||||
|
web.server.Server.changeMode(web.server.Server.ServerMode.IDLE)
|
||||||
|
return Waypoints.BuilderWaypoints(IntArray(0), IntArray(0), IntArray(0), IntArray(0), true).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
val begin_x = IntArray(10)
|
||||||
|
val begin_y = IntArray(10)
|
||||||
|
val end_x = IntArray(10)
|
||||||
|
val end_y = IntArray(10)
|
||||||
|
|
||||||
|
for (i in 0..9) {
|
||||||
|
begin_x[i] = currentPosition_x
|
||||||
|
begin_y[i] = currentPosition_y
|
||||||
|
|
||||||
|
currentPosition_x += rng.nextInt(3)
|
||||||
|
currentPosition_y += rng.nextInt(3)
|
||||||
|
|
||||||
|
end_x[i] = currentPosition_x
|
||||||
|
end_y[i] = currentPosition_y
|
||||||
|
}
|
||||||
|
iter++
|
||||||
|
return Waypoints.BuilderWaypoints(begin_x, begin_y, end_x, end_y, false).build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -98,6 +98,7 @@ class ClientHandler : SimpleChannelInboundHandler<Any> {
|
|||||||
|
|
||||||
override fun channelRead0(ctx: ChannelHandlerContext?, msg: Any?) {
|
override fun channelRead0(ctx: ChannelHandlerContext?, msg: Any?) {
|
||||||
if (msg is DefaultHttpContent) {
|
if (msg is DefaultHttpContent) {
|
||||||
|
// TODO: refactor variable names. It's hard as hell to read code with "contentBytes" and "content(!)s(!)Bytes" in lines of code.
|
||||||
val contentsBytes = msg.content()
|
val contentsBytes = msg.content()
|
||||||
contentBytes = ByteArray(contentsBytes.capacity())
|
contentBytes = ByteArray(contentsBytes.capacity())
|
||||||
contentsBytes.readBytes(contentBytes)
|
contentsBytes.readBytes(contentBytes)
|
||||||
|
|||||||
@@ -5,26 +5,117 @@ import io.netty.channel.ChannelHandlerContext
|
|||||||
import io.netty.channel.SimpleChannelInboundHandler
|
import io.netty.channel.SimpleChannelInboundHandler
|
||||||
import io.netty.handler.codec.http.*
|
import io.netty.handler.codec.http.*
|
||||||
import io.netty.util.CharsetUtil
|
import io.netty.util.CharsetUtil
|
||||||
|
import GenericResponse
|
||||||
|
import CodedOutputStream
|
||||||
|
import CodedInputStream
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class Handler : SimpleChannelInboundHandler<Any>() {
|
class Handler : SimpleChannelInboundHandler<Any>() {
|
||||||
|
|
||||||
var contentBytes: ByteArray = ByteArray(0)
|
var contentBytes: ByteArray = ByteArray(0)
|
||||||
|
var url: String? = null
|
||||||
|
var method: HttpMethod? = null
|
||||||
|
|
||||||
override fun channelReadComplete(ctx: ChannelHandlerContext) {
|
override fun channelReadComplete(ctx: ChannelHandlerContext) {
|
||||||
|
when (url) {
|
||||||
|
Constants.changeModeURL -> {
|
||||||
|
if (Server.serverMode != Server.ServerMode.IDLE && Server.serverMode != Server.ServerMode.MANUAL_MODE) {
|
||||||
|
throw IllegalStateException("Can't change server mode in algorithm execution mode!")
|
||||||
|
}
|
||||||
|
|
||||||
val response = DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer("" + Math.random() * 10000, CharsetUtil.UTF_8))
|
// Parse mode change request
|
||||||
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
|
val ins = CodedInputStream(Base64.getDecoder().decode(contentBytes))
|
||||||
ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
|
val request = ModeChange.BuilderModeChange(ModeChange.Mode.ManualControl).parseFrom(ins)
|
||||||
}
|
|
||||||
|
|
||||||
override fun channelRead0(ctx: ChannelHandlerContext, msg: Any) {
|
// Change server mode
|
||||||
if (msg is DefaultHttpContent) {
|
Server.changeMode(Server.ServerMode.fromProtoMode(request.newMode))
|
||||||
val contentsBytes = msg.content()
|
|
||||||
contentBytes = ByteArray(contentsBytes.capacity())
|
// Respond with "OK"-protobuf
|
||||||
contentsBytes.readBytes(contentBytes)
|
val protoResponse = GenericResponse.BuilderGenericResponse(Result.BuilderResult(0).build())
|
||||||
|
val outs = CodedOutputStream(ByteArray(protoResponse.getSizeNoTag()))
|
||||||
|
protoResponse.writeTo(outs)
|
||||||
|
val response = DefaultFullHttpResponse(
|
||||||
|
HttpVersion.HTTP_1_1,
|
||||||
|
HttpResponseStatus.OK,
|
||||||
|
Unpooled.copiedBuffer(Base64.getEncoder().encodeToString(outs.buffer), CharsetUtil.UTF_8)
|
||||||
|
)
|
||||||
|
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
|
||||||
|
response.headers().add("Access-Control-Allow-Origin", "*");
|
||||||
|
response.headers().add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
|
||||||
|
response.headers().add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
|
||||||
|
ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
|
||||||
|
}
|
||||||
|
Constants.getWaypointsURL -> {
|
||||||
|
if (Server.serverMode != Server.ServerMode.PERIMETER_BUILDING) {
|
||||||
|
throw IllegalStateException("Can't get waypoints when in not Permiter Building mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build update for UI
|
||||||
|
val msg = RoomModel.getUpdate()
|
||||||
|
val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag()))
|
||||||
|
msg.writeTo(outs)
|
||||||
|
val response = DefaultFullHttpResponse(
|
||||||
|
HttpVersion.HTTP_1_1,
|
||||||
|
HttpResponseStatus.OK,
|
||||||
|
Unpooled.copiedBuffer(Base64.getEncoder().encodeToString(outs.buffer), CharsetUtil.UTF_8)
|
||||||
|
)
|
||||||
|
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
|
||||||
|
response.headers().add("Access-Control-Allow-Origin", "*");
|
||||||
|
response.headers().add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
|
||||||
|
response.headers().add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
|
||||||
|
ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
|
||||||
|
}
|
||||||
|
Constants.directionOrderURL -> {
|
||||||
|
if (Server.serverMode != Server.ServerMode.MANUAL_MODE) {
|
||||||
|
throw IllegalStateException("Can't execute move order when not in manual mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse direction order
|
||||||
|
val ins = CodedInputStream(contentBytes)
|
||||||
|
val order = DirectionRequest.BuilderDirectionRequest(DirectionRequest.Command.FORWARD, 0, false).parseFrom(ins)
|
||||||
|
if (order.stop) {
|
||||||
|
web.server.Server.changeMode(Server.ServerMode.IDLE)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCarOrder(order.command)
|
||||||
|
|
||||||
|
// TODO: should be done as callback after sending car order
|
||||||
|
// Send update back
|
||||||
|
val msg = RoomModel.getUpdate()
|
||||||
|
val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag()))
|
||||||
|
msg.writeTo(outs)
|
||||||
|
val response = DefaultFullHttpResponse(
|
||||||
|
HttpVersion.HTTP_1_1,
|
||||||
|
HttpResponseStatus.OK,
|
||||||
|
Unpooled.copiedBuffer(Base64.getEncoder().encodeToString(outs.buffer), CharsetUtil.UTF_8)
|
||||||
|
)
|
||||||
|
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
|
||||||
|
response.headers().add("Access-Control-Allow-Origin", "*");
|
||||||
|
response.headers().add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
|
||||||
|
response.headers().add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
|
||||||
|
ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: stub!!
|
||||||
|
fun sendCarOrder(cmd: DirectionRequest.Command) {
|
||||||
|
println("Sent order ${cmd.toString()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun channelRead0(ctx: ChannelHandlerContext, msg: Any) {
|
||||||
|
if (msg is HttpRequest) {
|
||||||
|
url = msg.uri()
|
||||||
|
method = msg.method()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg is DefaultHttpContent) {
|
||||||
|
val contentBuffer = msg.content()
|
||||||
|
contentBytes = ByteArray(contentBuffer.capacity())
|
||||||
|
contentBuffer.readBytes(contentBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
|
override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
|
||||||
println("exception")
|
println("exception")
|
||||||
|
|||||||
@@ -6,7 +6,30 @@ import io.netty.channel.socket.nio.NioServerSocketChannel
|
|||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
object Server {
|
object Server {
|
||||||
|
enum class ServerMode {
|
||||||
|
IDLE,
|
||||||
|
MANUAL_MODE,
|
||||||
|
PERIMETER_BUILDING;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromProtoMode(mode: ModeChange.Mode): ServerMode {
|
||||||
|
return when (mode) {
|
||||||
|
ModeChange.Mode.ManualControl -> MANUAL_MODE
|
||||||
|
ModeChange.Mode.PerimeterBuilding -> PERIMETER_BUILDING
|
||||||
|
else -> throw IllegalArgumentException("Illegal argument when parsing ServerMode from Protobuf Mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val handlerThreadsCount: Int = 10
|
private val handlerThreadsCount: Int = 10
|
||||||
|
var serverMode = ServerMode.IDLE
|
||||||
|
|
||||||
|
fun changeMode(newMode: ServerMode) {
|
||||||
|
println("Changing mode from ${serverMode.toString()} to ${newMode.toString()}")
|
||||||
|
serverMode = newMode
|
||||||
|
}
|
||||||
|
|
||||||
fun getWebServerThread(webServerPort: Int): Thread {
|
fun getWebServerThread(webServerPort: Int): Thread {
|
||||||
return thread(false, false, null, "webServer", -1, {
|
return thread(false, false, null, "webServer", -1, {
|
||||||
println("web server started")
|
println("web server started")
|
||||||
|
|||||||
Reference in New Issue
Block a user