diff --git a/src/main/kotlin/spark/kotlin/Http.kt b/src/main/kotlin/spark/kotlin/Http.kt index 574aacd..c7fa389 100644 --- a/src/main/kotlin/spark/kotlin/Http.kt +++ b/src/main/kotlin/spark/kotlin/Http.kt @@ -242,7 +242,24 @@ fun internalServerError(function: RouteHandler.() -> Any) { } } -//----------------- TODO: Web sockets -----------------// +//----------------- Web sockets -----------------// + +/** + * Registers a WebSocket handler class under a given URL. + * @param url The URL to attach the WebSocket handler to. + * @param handler A class annotated with Jetty's WebSocket annotations. + */ +fun webSocket(url: String, handler: KClass<*>) { + Spark.webSocket(url, handler.java) +} + +/** + * Sets the idle timeout for WebSocket connections. + * @param timeout The amount of time, in milliseconds, that a connection can remain established for with no activity. + */ +fun webSocketIdleTimeoutMillis(timeout: Int) { + Spark.webSocketIdleTimeoutMillis(timeout) +} //----------------- exception mapping -----------------// @@ -473,6 +490,16 @@ class Http(val service: Service) { //----------------- Redirect -----------------// val redirect: Redirect = service.redirect + //----------------- WebSockets ------------------// + // These behave in exactly the same way as the static WebSocket methods. + fun webSocket(path: String, handler: KClass<*>) { + service.webSocket(path, handler.java) + } + + fun webSocketIdleTimeoutMillis(timeout: Int) { + service.webSocketIdleTimeoutMillis(timeout) + } + /** * Gets the port */ diff --git a/src/test/kotlin/spark/examples/instance/InstanceApiExample.kt b/src/test/kotlin/spark/examples/instance/InstanceApiExample.kt index d378dc1..3cdd816 100644 --- a/src/test/kotlin/spark/examples/instance/InstanceApiExample.kt +++ b/src/test/kotlin/spark/examples/instance/InstanceApiExample.kt @@ -15,7 +15,7 @@ */ package spark.examples.instance -import org.omg.CosNaming.NamingContextPackage.NotFound +import spark.examples.testutil.SampleWebSocketHandler import spark.kotlin.Http import spark.kotlin.halt import spark.kotlin.ignite @@ -28,6 +28,8 @@ fun main(args: Array) { val http: Http = ignite() + http.webSocket("/ws", SampleWebSocketHandler::class) + http.staticFiles.location("/public") http.get("/hello") { @@ -75,4 +77,5 @@ fun main(args: Array) { } } + class NotFoundException(message: String) : Exception(message) diff --git a/src/test/kotlin/spark/examples/static/StaticApiExample.kt b/src/test/kotlin/spark/examples/static/StaticApiExample.kt index 416fab5..d15ecf6 100644 --- a/src/test/kotlin/spark/examples/static/StaticApiExample.kt +++ b/src/test/kotlin/spark/examples/static/StaticApiExample.kt @@ -15,12 +15,14 @@ */ package spark.examples.static +import spark.examples.testutil.SampleWebSocketHandler import spark.kotlin.* /** * Example usage of spark-kotlin via STATIC API. */ fun main(args: Array) { + webSocket("/ws", SampleWebSocketHandler::class) staticFiles.location("/public") diff --git a/src/test/kotlin/spark/examples/testutil/SampleWebSocketHandler.kt b/src/test/kotlin/spark/examples/testutil/SampleWebSocketHandler.kt new file mode 100644 index 0000000..de7c038 --- /dev/null +++ b/src/test/kotlin/spark/examples/testutil/SampleWebSocketHandler.kt @@ -0,0 +1,36 @@ +package spark.examples.testutil + +import org.eclipse.jetty.websocket.api.Session +import org.eclipse.jetty.websocket.api.annotations.* +import java.io.InputStream + +@WebSocket class SampleWebSocketHandler { + @OnWebSocketConnect + fun onConnect(s: Session) { + println("${s.remoteAddress} has opened a WebSocket connection.") + } + + @OnWebSocketError + fun onError(s: Session, t: Throwable) { + println("An error was encountered on ${s.remoteAddress}' connection: $t") + } + + // Handles text messages by echoing them back to the sender + @OnWebSocketMessage + fun onMessage(s: Session, msg: String) { + println("Message received from ${s.remoteAddress}: $msg") + s.remote.sendString(msg) + } + + // Handles binary messages + @OnWebSocketMessage + fun onMessage(s: Session, input: InputStream) { + println("Binary message received from ${s.remoteAddress}") + } + + @OnWebSocketClose + fun onClose(s: Session, code: Int, reason: String) { + println("${s.remoteAddress} has closed their connection: $code ($reason)") + } + +}