handleWebSocketMessagesForProtocol
Signature
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 Server-Side WebSocket Support.
Example
def greeterService: Flow[Message, Message, Any] =
Flow[Message].mapConcat {
case tm: TextMessage =>
TextMessage(Source.single("Hello ") ++ tm.textStream ++ Source.single("!")) :: Nil
case bm: BinaryMessage =>
// ignore binary messages but drain content to avoid the stream being clogged
bm.dataStream.runWith(Sink.ignore)
Nil
}
def echoService: Flow[Message, Message, Any] =
Flow[Message]
// needed because a noop flow hasn't any buffer that would start processing in tests
.buffer(1, OverflowStrategy.backpressure)
def websocketMultipleProtocolRoute =
path("services") {
handleWebSocketMessagesForProtocol(greeterService, "greeter") ~
handleWebSocketMessagesForProtocol(echoService, "echo")
}
// tests:
val wsClient = WSProbe()
// WS creates a WebSocket request for testing
WS("/services", wsClient.flow, List("other", "echo")) ~>
websocketMultipleProtocolRoute ~>
check {
expectWebSocketUpgradeWithProtocol { protocol =>
protocol shouldEqual "echo"
wsClient.sendMessage("Peter")
wsClient.expectMessage("Peter")
wsClient.sendMessage(BinaryMessage(ByteString("abcdef")))
wsClient.expectMessage(ByteString("abcdef"))
wsClient.sendMessage("John")
wsClient.expectMessage("John")
wsClient.sendCompletion()
wsClient.expectCompletion()
}
}
Contents