Hello,

(this is more related to akka-http but there seem to be no dedicated group)

I am trying to setup a websocket server for which there is no 1-1 relation 
between incoming and outgoing messages. The client can send messages at any 
time which may or not have a reply from the server. The server can push 
messages at any time which may or not have a reply from the client. I 
wanted to let actors handle and produce these messages. Following the doc 
<http://doc.akka.io/docs/akka-http/current/java/http/server-side/websocket-support.html#handling-messages>
 
I am using Sink#actorRefWithAck to push incoming messages to the 
entrypoint/router actor and let it do it's job. For outgoing messages in 
the options suggested by the doc 
<http://doc.akka.io/docs/akka/current/scala/stream/stream-integrations.html#Integrating_with_Actors>
 
I was planning to use Source#queue and give this queue to all the actors 
which might need to push to the queue. I targeted this solution because it 
allows for backpressure management.

My issue is that I need access to the queue materialized value (in order to 
call offer) but WebSocket#handleWebSocketRequestWith does not provide 
access to it. It returns only the HttpResponse to send back to the client.

Source<Message, SourceQueueWithComplete<Message>> queue = 
Source.<Message>queue(5, OverflowStrategy.backpressure());
Sink<Message, NotUsed> sink = Sink.actorRefWithAck(tunnel, Messages.INIT, 
Messages.ACK, Messages.COMPLETE, this::onError);
Flow<Message, Message, SourceQueueWithComplete<Message>> flow = 
Flow.fromSinkAndSourceMat(sink, queue, Keep.right());
HttpResponse response = WebSocket.handleWebSocketRequestWith(request, 
greeterFlow);

I tried the "lower level" UpgradeToWebSocket#handleMessagesWith but got to 
the same conclusion: only the HTTP response is returned back:

HttpResponse response = 
((UpgradeToWebSocket)header).handleMessagesWith(sink, queue);

I worked around the issue by using mapMaterializedValue, which gives me the 
materialized value which I can give to my handler actor for them to publish 
on. But it sounds like a hack and I would prefer not having side effects in 
mapMaterliazedValue:

Source.<Message>queue(5, OverflowStrategy.backpressure())
    .mapMaterializedValue(sourceQueue -> { 
tunnel.tell(InitTunnel.create(sourceQueue), Actor.noSender()); return 
sourceQueue; });

On the other side, the client gives it back:

Pair<CompletionStage<WebSocketUpgradeResponse>, 
SourceQueueWithComplete<Message>> pair =
        http.singleWebSocketRequest(WebSocketRequest.create(connect), flow, 
materializer);

I wonder if I am misusing the API or there is a miss here. If nothing in 
the API lets users do that, would that be a desirable addition?

While debugging I saw that the graph is materialized after the response is 
sent back, so there might be a technical limitation which I am not aware of 
that forces to materialize the graph later.

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to