From 2fc9fd22084bb4a89a72be525c18fc409303ada5 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 13 Aug 2018 03:54:50 +0800 Subject: Basic websocket support works --- example/endpoints/app/src/Endpoints.scala | 5 ++- example/websockets/app/src/Websockets.scala | 29 +++++++++++++ example/websockets/app/test/src/ExampleTests.scala | 47 ++++++++++++++++++++++ example/websockets/build.sc | 19 +++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 example/websockets/app/src/Websockets.scala create mode 100644 example/websockets/app/test/src/ExampleTests.scala create mode 100644 example/websockets/build.sc (limited to 'example') diff --git a/example/endpoints/app/src/Endpoints.scala b/example/endpoints/app/src/Endpoints.scala index e2a14dc..9eadf39 100644 --- a/example/endpoints/app/src/Endpoints.scala +++ b/example/endpoints/app/src/Endpoints.scala @@ -1,7 +1,10 @@ package app +import cask.main.HttpDecorator +import cask.model.ParamContext -class custom(val path: String, val methods: Seq[String]) extends cask.Endpoint{ + +class custom(val path: String, val methods: Seq[String]) extends cask.Endpoint with HttpDecorator{ type Output = Int def wrapFunction(ctx: cask.ParamContext, delegate: Delegate): Returned = { delegate(Map()).map{num => diff --git a/example/websockets/app/src/Websockets.scala b/example/websockets/app/src/Websockets.scala new file mode 100644 index 0000000..277b06f --- /dev/null +++ b/example/websockets/app/src/Websockets.scala @@ -0,0 +1,29 @@ +package app + +import io.undertow.websockets.WebSocketConnectionCallback +import io.undertow.websockets.core.{AbstractReceiveListener, BufferedTextMessage, WebSocketChannel, WebSockets} +import io.undertow.websockets.spi.WebSocketHttpExchange + +object Websockets extends cask.MainRoutes{ + @cask.websocket("/connect/:userName") + def showUserProfile(userName: String): cask.WebsocketResult = { + if (userName != "haoyi") cask.Response("", statusCode = 403) + else new WebSocketConnectionCallback() { + override def onConnect(exchange: WebSocketHttpExchange, channel: WebSocketChannel): Unit = { + channel.getReceiveSetter.set( + new AbstractReceiveListener() { + override def onFullTextMessage(channel: WebSocketChannel, message: BufferedTextMessage) = { + val data = message.getData + if (data == "") channel.close() + else WebSockets.sendTextBlocking(userName + " " + data, channel) + } + } + ) + channel.resumeReceives() + + } + } + } + + initialize() +} diff --git a/example/websockets/app/test/src/ExampleTests.scala b/example/websockets/app/test/src/ExampleTests.scala new file mode 100644 index 0000000..01863e8 --- /dev/null +++ b/example/websockets/app/test/src/ExampleTests.scala @@ -0,0 +1,47 @@ +package app +import com.github.andyglow.websocket.WebsocketClient +import utest._ + +object ExampleTests extends TestSuite{ + def test[T](example: cask.main.BaseMain)(f: String => T): T = { + val server = io.undertow.Undertow.builder + .addHttpListener(8080, "localhost") + .setHandler(example.defaultHandler) + .build + server.start() + val res = + try f("http://localhost:8080") + finally server.stop() + res + } + + val tests = Tests{ + 'VariableRoutes - test(Websockets){ host => + @volatile var out = List.empty[String] + val cli = WebsocketClient[String]("ws://localhost:8080/connect/haoyi") { + case str => out = str :: out + } + + // 4. open websocket + val ws = cli.open() + + // 5. send messages + ws ! "hello" + ws ! "world" + ws ! "" + Thread.sleep(100) + out ==> List("haoyi world", "haoyi hello") + + val cli2 = WebsocketClient[String]("ws://localhost:8080/connect/nobody") { + case str => out = str :: out + } + + val error = + try cli2.open() + catch{case e: Throwable => e.getMessage} + + assert(error.toString.contains("Invalid handshake response getStatus: 403 Forbidden")) + } + + } +} diff --git a/example/websockets/build.sc b/example/websockets/build.sc new file mode 100644 index 0000000..bc8cf26 --- /dev/null +++ b/example/websockets/build.sc @@ -0,0 +1,19 @@ +import mill._, scalalib._ + + +trait AppModule extends ScalaModule{ + def scalaVersion = "2.12.6" + def ivyDeps = Agg( + ivy"com.lihaoyi::cask:0.0.1", + ) + + object test extends Tests{ + def testFrameworks = Seq("utest.runner.Framework") + + def ivyDeps = Agg( + ivy"com.lihaoyi::utest::0.6.3", + ivy"com.lihaoyi::requests::0.1.2", + ivy"com.github.andyglow::websocket-scala-client:0.2.4" + ) + } +} \ No newline at end of file -- cgit v1.2.3