!htc,doc,htp #19508 fix casing of WebSocket (as per spec)

This commit is contained in:
Konrad Malawski 2016-01-19 20:43:59 +01:00
parent 0dd889aa17
commit 1b47fbeac7
72 changed files with 698 additions and 501 deletions

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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]``

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,10 +1,10 @@
.. _WebsocketDirectives:
.. _WebSocketDirectives:
WebsocketDirectives
WebSocketDirectives
===================
.. toctree::
:maxdepth: 1
handleWebsocketMessages
handleWebsocketMessagesForProtocol
handleWebSocketMessages
handleWebSocketMessagesForProtocol

View file

@ -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