!htc,doc,htp #19508 fix casing of WebSocket (as per spec)
This commit is contained in:
parent
0dd889aa17
commit
1b47fbeac7
72 changed files with 698 additions and 501 deletions
|
|
@ -8,7 +8,7 @@ import akka.http.scaladsl.model.ws.BinaryMessage
|
|||
import akka.stream.scaladsl.Sink
|
||||
import org.scalatest.{ Matchers, WordSpec }
|
||||
|
||||
class WebsocketExampleSpec extends WordSpec with Matchers {
|
||||
class WebSocketExampleSpec extends WordSpec with Matchers {
|
||||
"core-example" in {
|
||||
pending // compile-time only test
|
||||
//#websocket-example-using-core
|
||||
|
|
@ -16,7 +16,7 @@ class WebsocketExampleSpec extends WordSpec with Matchers {
|
|||
import akka.stream.ActorMaterializer
|
||||
import akka.stream.scaladsl.{ Source, Flow }
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.model.ws.UpgradeToWebsocket
|
||||
import akka.http.scaladsl.model.ws.UpgradeToWebSocket
|
||||
import akka.http.scaladsl.model.ws.{ TextMessage, Message }
|
||||
import akka.http.scaladsl.model.{ HttpResponse, Uri, HttpRequest }
|
||||
import akka.http.scaladsl.model.HttpMethods._
|
||||
|
|
@ -27,7 +27,7 @@ class WebsocketExampleSpec extends WordSpec with Matchers {
|
|||
//#websocket-handler
|
||||
// The Greeter WebSocket Service expects a "name" per message and
|
||||
// returns a greeting message for that name
|
||||
val greeterWebsocketService =
|
||||
val greeterWebSocketService =
|
||||
Flow[Message]
|
||||
.mapConcat {
|
||||
// we match but don't actually consume the text message here,
|
||||
|
|
@ -45,8 +45,8 @@ class WebsocketExampleSpec extends WordSpec with Matchers {
|
|||
//#websocket-request-handling
|
||||
val requestHandler: HttpRequest ⇒ HttpResponse = {
|
||||
case req @ HttpRequest(GET, Uri.Path("/greeter"), _, _, _) ⇒
|
||||
req.header[UpgradeToWebsocket] match {
|
||||
case Some(upgrade) ⇒ upgrade.handleMessages(greeterWebsocketService)
|
||||
req.header[UpgradeToWebSocket] match {
|
||||
case Some(upgrade) ⇒ upgrade.handleMessages(greeterWebSocketService)
|
||||
case None ⇒ HttpResponse(400, entity = "Not a valid websocket request!")
|
||||
}
|
||||
case _: HttpRequest ⇒ HttpResponse(404, entity = "Unknown resource!")
|
||||
|
|
@ -80,7 +80,7 @@ class WebsocketExampleSpec extends WordSpec with Matchers {
|
|||
|
||||
// The Greeter WebSocket Service expects a "name" per message and
|
||||
// returns a greeting message for that name
|
||||
val greeterWebsocketService =
|
||||
val greeterWebSocketService =
|
||||
Flow[Message]
|
||||
.collect {
|
||||
case tm: TextMessage ⇒ TextMessage(Source.single("Hello ") ++ tm.textStream)
|
||||
|
|
@ -91,7 +91,7 @@ class WebsocketExampleSpec extends WordSpec with Matchers {
|
|||
val route =
|
||||
path("greeter") {
|
||||
get {
|
||||
handleWebsocketMessages(greeterWebsocketService)
|
||||
handleWebSocketMessages(greeterWebSocketService)
|
||||
}
|
||||
}
|
||||
//#websocket-routing
|
||||
|
|
@ -15,7 +15,7 @@ import docs.http.scaladsl.server.RoutingSpec
|
|||
import akka.http.scaladsl.model.ws.{ TextMessage, Message, BinaryMessage }
|
||||
import akka.http.scaladsl.testkit.WSProbe
|
||||
|
||||
class WebsocketDirectivesExamplesSpec extends RoutingSpec {
|
||||
class WebSocketDirectivesExamplesSpec extends RoutingSpec {
|
||||
"greeter-service" in {
|
||||
def greeter: Flow[Message, Message, Any] =
|
||||
Flow[Message].mapConcat {
|
||||
|
|
@ -28,18 +28,18 @@ class WebsocketDirectivesExamplesSpec extends RoutingSpec {
|
|||
}
|
||||
val websocketRoute =
|
||||
path("greeter") {
|
||||
handleWebsocketMessages(greeter)
|
||||
handleWebSocketMessages(greeter)
|
||||
}
|
||||
|
||||
// tests:
|
||||
// create a testing probe representing the client-side
|
||||
val wsClient = WSProbe()
|
||||
|
||||
// WS creates a Websocket request for testing
|
||||
// WS creates a WebSocket request for testing
|
||||
WS("/greeter", wsClient.flow) ~> websocketRoute ~>
|
||||
check {
|
||||
// check response for WS Upgrade headers
|
||||
isWebsocketUpgrade shouldEqual true
|
||||
isWebSocketUpgrade shouldEqual true
|
||||
|
||||
// manually run a WS conversation
|
||||
wsClient.sendMessage("Peter")
|
||||
|
|
@ -74,18 +74,18 @@ class WebsocketDirectivesExamplesSpec extends RoutingSpec {
|
|||
|
||||
def websocketMultipleProtocolRoute =
|
||||
path("services") {
|
||||
handleWebsocketMessagesForProtocol(greeterService, "greeter") ~
|
||||
handleWebsocketMessagesForProtocol(echoService, "echo")
|
||||
handleWebSocketMessagesForProtocol(greeterService, "greeter") ~
|
||||
handleWebSocketMessagesForProtocol(echoService, "echo")
|
||||
}
|
||||
|
||||
// tests:
|
||||
val wsClient = WSProbe()
|
||||
|
||||
// WS creates a Websocket request for testing
|
||||
// WS creates a WebSocket request for testing
|
||||
WS("/services", wsClient.flow, List("other", "echo")) ~>
|
||||
websocketMultipleProtocolRoute ~>
|
||||
check {
|
||||
expectWebsocketUpgradeWithProtocol { protocol ⇒
|
||||
expectWebSocketUpgradeWithProtocol { protocol ⇒
|
||||
protocol shouldEqual "echo"
|
||||
|
||||
wsClient.sendMessage("Peter")
|
||||
|
|
@ -12,7 +12,7 @@ It sports the following features:
|
|||
- Full support for `HTTP pipelining`_
|
||||
- Full support for asynchronous HTTP streaming including "chunked" transfer encoding accessible through an idiomatic API
|
||||
- Optional SSL/TLS encryption
|
||||
- Websocket support
|
||||
- WebSocket support
|
||||
|
||||
.. _HTTP persistent connections: http://en.wikipedia.org/wiki/HTTP_persistent_connection
|
||||
.. _HTTP pipelining: http://en.wikipedia.org/wiki/HTTP_pipelining
|
||||
|
|
|
|||
|
|
@ -86,11 +86,11 @@ Directive Description
|
|||
given ``ExceptionHandler``
|
||||
:ref:`-handleRejections-` Transforms rejections produced by the inner route using the given
|
||||
``RejectionHandler``
|
||||
:ref:`-handleWebsocketMessages-` Handles websocket requests with the given handler and rejects other requests
|
||||
with an ``ExpectedWebsocketRequestRejection``
|
||||
:ref:`-handleWebsocketMessagesForProtocol-` Handles websocket requests with the given handler if the subprotocol matches
|
||||
and rejects other requests with an ``ExpectedWebsocketRequestRejection`` or
|
||||
an ``UnsupportedWebsocketSubprotocolRejection``.
|
||||
:ref:`-handleWebSocketMessages-` Handles websocket requests with the given handler and rejects other requests
|
||||
with an ``ExpectedWebSocketRequestRejection``
|
||||
:ref:`-handleWebSocketMessagesForProtocol-` Handles websocket requests with the given handler if the subprotocol matches
|
||||
and rejects other requests with an ``ExpectedWebSocketRequestRejection`` or
|
||||
an ``UnsupportedWebSocketSubprotocolRejection``.
|
||||
:ref:`-handleWith-` Completes the request using a given function
|
||||
:ref:`-head-` Rejects all non-HEAD requests
|
||||
:ref:`-headerValue-` Extracts an HTTP header value using a given ``HttpHeader ⇒ Option[T]``
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
.. _-handleWebsocketMessages-:
|
||||
.. _-handleWebSocketMessages-:
|
||||
|
||||
handleWebsocketMessages
|
||||
handleWebSocketMessages
|
||||
=======================
|
||||
|
||||
Signature
|
||||
---------
|
||||
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/WebsocketDirectives.scala
|
||||
:snippet: handleWebsocketMessages
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/WebSocketDirectives.scala
|
||||
:snippet: handleWebSocketMessages
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The directive first checks if the request was a valid Websocket handshake request and if yes, it completes the request
|
||||
with the passed handler. Otherwise, the request is rejected with an ``ExpectedWebsocketRequestRejection``.
|
||||
The directive first checks if the request was a valid WebSocket handshake request and if yes, it completes the request
|
||||
with the passed handler. Otherwise, the request is rejected with an ``ExpectedWebSocketRequestRejection``.
|
||||
|
||||
Websocket subprotocols offered in the ``Sec-Websocket-Protocol`` header of the request are ignored. If you want to
|
||||
support several protocols use the :ref:`-handleWebsocketMessagesForProtocol-` directive, instead.
|
||||
WebSocket subprotocols offered in the ``Sec-WebSocket-Protocol`` header of the request are ignored. If you want to
|
||||
support several protocols use the :ref:`-handleWebSocketMessagesForProtocol-` directive, instead.
|
||||
|
||||
For more information about the Websocket support, see :ref:`server-side-websocket-support-scala`.
|
||||
For more information about the WebSocket support, see :ref:`server-side-websocket-support-scala`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/WebsocketDirectivesExamplesSpec.scala
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/WebSocketDirectivesExamplesSpec.scala
|
||||
:snippet: greeter-service
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
.. _-handleWebSocketMessagesForProtocol-:
|
||||
|
||||
handleWebSocketMessagesForProtocol
|
||||
==================================
|
||||
|
||||
Signature
|
||||
---------
|
||||
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/WebSocketDirectives.scala
|
||||
:snippet: handleWebSocketMessagesForProtocol
|
||||
|
||||
Description
|
||||
-----------
|
||||
Handles WebSocket requests with the given handler if the given subprotocol is offered in the ``Sec-WebSocket-Protocol``
|
||||
header of the request and rejects other requests with an ``ExpectedWebSocketRequestRejection`` or an
|
||||
``UnsupportedWebSocketSubprotocolRejection``.
|
||||
|
||||
The directive first checks if the request was a valid WebSocket handshake request and if the request offers the passed
|
||||
subprotocol name. If yes, the directive completes the request with the passed handler. Otherwise, the request is
|
||||
either rejected with an ``ExpectedWebSocketRequestRejection`` or an ``UnsupportedWebSocketSubprotocolRejection``.
|
||||
|
||||
To support several subprotocols, for example at the same path, several instances of ``handleWebSocketMessagesForProtocol`` can
|
||||
be chained using ``~`` as you can see in the below example.
|
||||
|
||||
For more information about the WebSocket support, see :ref:`server-side-websocket-support-scala`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/WebSocketDirectivesExamplesSpec.scala
|
||||
:snippet: handle-multiple-protocols
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
.. _-handleWebsocketMessagesForProtocol-:
|
||||
|
||||
handleWebsocketMessagesForProtocol
|
||||
==================================
|
||||
|
||||
Signature
|
||||
---------
|
||||
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/WebsocketDirectives.scala
|
||||
:snippet: handleWebsocketMessagesForProtocol
|
||||
|
||||
Description
|
||||
-----------
|
||||
Handles Websocket requests with the given handler if the given subprotocol is offered in the ``Sec-Websocket-Protocol``
|
||||
header of the request and rejects other requests with an ``ExpectedWebsocketRequestRejection`` or an
|
||||
``UnsupportedWebsocketSubprotocolRejection``.
|
||||
|
||||
The directive first checks if the request was a valid Websocket handshake request and if the request offers the passed
|
||||
subprotocol name. If yes, the directive completes the request with the passed handler. Otherwise, the request is
|
||||
either rejected with an ``ExpectedWebsocketRequestRejection`` or an ``UnsupportedWebsocketSubprotocolRejection``.
|
||||
|
||||
To support several subprotocols, for example at the same path, several instances of ``handleWebsocketMessagesForProtocol`` can
|
||||
be chained using ``~`` as you can see in the below example.
|
||||
|
||||
For more information about the Websocket support, see :ref:`server-side-websocket-support-scala`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/WebsocketDirectivesExamplesSpec.scala
|
||||
:snippet: handle-multiple-protocols
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
.. _WebsocketDirectives:
|
||||
.. _WebSocketDirectives:
|
||||
|
||||
WebsocketDirectives
|
||||
WebSocketDirectives
|
||||
===================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
handleWebsocketMessages
|
||||
handleWebsocketMessagesForProtocol
|
||||
handleWebSocketMessages
|
||||
handleWebSocketMessagesForProtocol
|
||||
|
|
@ -44,20 +44,20 @@ to create a streaming message from an Akka Stream source.
|
|||
Server API
|
||||
----------
|
||||
|
||||
The entrypoint for the Websocket API is the synthetic ``UpgradeToWebsocket`` header which is added to a request
|
||||
if Akka HTTP encounters a Websocket upgrade request.
|
||||
The entrypoint for the WebSocket API is the synthetic ``UpgradeToWebSocket`` header which is added to a request
|
||||
if Akka HTTP encounters a WebSocket upgrade request.
|
||||
|
||||
The Websocket specification mandates that details of the Websocket connection are negotiated by placing special-purpose
|
||||
The WebSocket specification mandates that details of the WebSocket connection are negotiated by placing special-purpose
|
||||
HTTP-headers into request and response of the HTTP upgrade. In Akka HTTP these HTTP-level details of the WebSocket
|
||||
handshake are hidden from the application and don't need to be managed manually.
|
||||
|
||||
Instead, the synthetic ``UpgradeToWebsocket`` represents a valid Websocket upgrade request. An application can detect
|
||||
a Websocket upgrade request by looking for the ``UpgradeToWebsocket`` header. It can choose to accept the upgrade and
|
||||
start a Websocket connection by responding to that request with an ``HttpResponse`` generated by one of the
|
||||
``UpgradeToWebsocket.handleMessagesWith`` methods. In its most general form this method expects two arguments:
|
||||
first, a handler ``Flow[Message, Message, Any]`` that will be used to handle Websocket messages on this connection.
|
||||
Instead, the synthetic ``UpgradeToWebSocket`` represents a valid WebSocket upgrade request. An application can detect
|
||||
a WebSocket upgrade request by looking for the ``UpgradeToWebSocket`` header. It can choose to accept the upgrade and
|
||||
start a WebSocket connection by responding to that request with an ``HttpResponse`` generated by one of the
|
||||
``UpgradeToWebSocket.handleMessagesWith`` methods. In its most general form this method expects two arguments:
|
||||
first, a handler ``Flow[Message, Message, Any]`` that will be used to handle WebSocket messages on this connection.
|
||||
Second, the application can optionally choose one of the proposed application-level sub-protocols by inspecting the
|
||||
values of ``UpgradeToWebsocket.requestedProtocols`` and pass the chosen protocol value to ``handleMessages``.
|
||||
values of ``UpgradeToWebSocket.requestedProtocols`` and pass the chosen protocol value to ``handleMessages``.
|
||||
|
||||
Handling Messages
|
||||
+++++++++++++++++
|
||||
|
|
@ -68,7 +68,7 @@ scenarios this fits very well and such a ``Flow`` can be constructed from a simp
|
|||
|
||||
There are other use-cases, e.g. in a server-push model, where a server message is sent spontaneously, or in a
|
||||
true bi-directional scenario where input and output aren't logically connected. Providing the handler as a ``Flow`` in
|
||||
these cases may not fit. Another method, ``UpgradeToWebsocket.handleMessagesWithSinkSource``, is provided
|
||||
these cases may not fit. Another method, ``UpgradeToWebSocket.handleMessagesWithSinkSource``, is provided
|
||||
which allows to pass an output-generating ``Source[Message, Any]`` and an input-receiving ``Sink[Message, Any]`` independently.
|
||||
|
||||
Note that a handler is required to consume the data stream of each message to make place for new messages. Otherwise,
|
||||
|
|
@ -79,36 +79,36 @@ Example
|
|||
|
||||
Let's look at an example_.
|
||||
|
||||
Websocket requests come in like any other requests. In the example, requests to ``/greeter`` are expected to be
|
||||
Websocket requests:
|
||||
WebSocket requests come in like any other requests. In the example, requests to ``/greeter`` are expected to be
|
||||
WebSocket requests:
|
||||
|
||||
.. includecode:: ../../code/docs/http/scaladsl/server/WebsocketExampleSpec.scala
|
||||
.. includecode:: ../../code/docs/http/scaladsl/server/WebSocketExampleSpec.scala
|
||||
:include: websocket-request-handling
|
||||
|
||||
It uses pattern matching on the path and then inspects the request to query for the ``UpgradeToWebsocket`` header. If
|
||||
such a header is found, it is used to generate a response by passing a handler for Websocket messages to the
|
||||
It uses pattern matching on the path and then inspects the request to query for the ``UpgradeToWebSocket`` header. If
|
||||
such a header is found, it is used to generate a response by passing a handler for WebSocket messages to the
|
||||
``handleMessages`` method. If no such header is found a "400 Bad Request" response is generated.
|
||||
|
||||
The passed handler expects text messages where each message is expected to contain (a person's) name
|
||||
and then responds with another text message that contains a greeting:
|
||||
|
||||
.. includecode:: ../../code/docs/http/scaladsl/server/WebsocketExampleSpec.scala
|
||||
.. includecode:: ../../code/docs/http/scaladsl/server/WebSocketExampleSpec.scala
|
||||
:include: websocket-handler
|
||||
|
||||
Routing support
|
||||
---------------
|
||||
|
||||
The routing DSL provides the :ref:`-handleWebsocketMessages-` directive to install a WebSocket handler if the request
|
||||
The routing DSL provides the :ref:`-handleWebSocketMessages-` directive to install a WebSocket handler if the request
|
||||
was a WebSocket request. Otherwise, the directive rejects the request.
|
||||
|
||||
Here's the above simple request handler rewritten as a route:
|
||||
|
||||
.. includecode2:: ../../code/docs/http/scaladsl/server/directives/WebsocketDirectivesExamplesSpec.scala
|
||||
.. includecode2:: ../../code/docs/http/scaladsl/server/directives/WebSocketDirectivesExamplesSpec.scala
|
||||
:snippet: greeter-service
|
||||
|
||||
The example also includes code demonstrating the testkit support for Websocket services. It allows to create Websocket
|
||||
requests to run against a route using `WS` which can be used to provide a mock Websocket probe that allows manual
|
||||
testing of the Websocket handler's behavior if the request was accepted.
|
||||
The example also includes code demonstrating the testkit support for WebSocket services. It allows to create WebSocket
|
||||
requests to run against a route using `WS` which can be used to provide a mock WebSocket probe that allows manual
|
||||
testing of the WebSocket handler's behavior if the request was accepted.
|
||||
|
||||
|
||||
.. _example: @github@/akka-docs-dev/rst/scala/code/docs/http/scaladsl/server/WebsocketExampleSpec.scala
|
||||
.. _example: @github@/akka-docs-dev/rst/scala/code/docs/http/scaladsl/server/WebSocketExampleSpec.scala
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue