Issue by Tvaroh
_Monday Jan 04, 2016 at 12:50 GMT_
_Originally opened as https://github.com/akka/akka/issues/19346_
I create sink and source separately to serve websocket connections using akka-http:
val in: Sink[Message, Unit] = ???
val out: Source[Message, Unit] = ???
upgrade.handleMessagesWithSinkSource(in, out)
Input sink is defined as follows:
val in = flowImpl(connection.id, responder)
.to(Sink.actorRef[CommandContext](protocolHandler, CloseConnection(connection.id, connection.userId, responder)))
// parses incoming JSON messages
def flowImpl(connectionId: ConnectionId, responder: Responder): Flow[Message, CommandContext, Unit] = ???
The problem is that when websocket connection is closed no CloseConnection is sent to the protocolHandler actor behind the sink.
On the other hand, if I transform input flow with a PushStage and do ctx.finish() in its onPush method, then CloseConnection is sent as expected. It is counter-intuitive that this doesn't work for the former case though.
Comment by Tvaroh
_Monday Jan 04, 2016 at 12:53 GMT_
In the meantime I'm interested in a workaround for detecting when websocket connection is closed.
Comment by jrudolph
_Monday Jan 04, 2016 at 16:17 GMT_
This may be related to #19340. Did that work with 2.0-M3?
Comment by jrudolph
_Monday Jan 04, 2016 at 16:21 GMT_
Which side closes the connection in your case?
Comment by Tvaroh
_Monday Jan 04, 2016 at 18:00 GMT_
@jrudolph can't tell about 2.0-M3, it's a fresh code using 2.0.1 version. Regarding the closing side... I'm not sure - either Chrome's websocket client or akka-http itself. I'm not getting any exceptions in the log btw.
Comment by jrudolph
_Tuesday Jan 05, 2016 at 15:43 GMT_
I published a version with the fix for #19340 to https://oss.sonatype.org/content/repositories/netvirtual-void-1037. You need to include the resolver and then adapt the organization name for akka-http/akka-stream artifacts like this:
resolvers += "Staging" at "https://oss.sonatype.org/content/repositories/netvirtual-void-1037"
libraryDependencies += "net.virtual-void" %% "akka-http-core-experimental" % "2.0.1-ws-fix"
Could you check if that fixes it?
Comment by jrudolph
_Tuesday Jan 05, 2016 at 19:21 GMT_
As @ktoso explained in #19285 you need to finish the outgoing side (the Source side) to finally close the connection. Can you explain what you did exactly in the case where it worked?
Comment by jrudolph
_Tuesday Jan 05, 2016 at 19:38 GMT_
I created #19359 to discuss further measures to ensure that WS connection are actually closed when the peer closed the connections.
Comment by Tvaroh
_Wednesday Jan 06, 2016 at 06:18 GMT_
It never worked, only if I close connection from the server side using PushStage (both in and out):
def mkCloseConnectionStage(responder: Responder): Stage[CommandContext, CommandContext] =
new PushStage[CommandContext, CommandContext] {
override def onPush(command: CommandContext, ctx: Context[CommandContext]): SyncDirective =
if (command.commandType == CommandType.Disconnect) {
responder.finish()
ctx.finish()
} else {
ctx.push(command)
}
}
But I have no option to know that the connection is closed out of my control.
Comment by rkuhn
_Monday Mar 21, 2016 at 14:38 GMT_
This definitely smells like a bug, if it still persists.
Comment by Tvaroh
_Monday Mar 21, 2016 at 17:23 GMT_
@rkuhn and it definitely needs giving a kick for someone to fix. :)
Comment by ktoso
_Monday Mar 21, 2016 at 21:39 GMT_
I don't think kicking anyone will get this resolved :-)
Self contained reproducer would help us get started on it once we get to it though.
Comment by rklaehn
_Friday May 13, 2016 at 11:32 GMT_
I got the same problem. Is there a workaround or a fix in sight?
Any news?
Any update on this or an agreed upon workaround?
Edit: I got around this by setting up a paired sink and source via this example (which seems to be the prescribed fix anyway: https://github.com/akka/akka-http/issues/860#issuecomment-317696052):
https://github.com/calvinlfer/akka-http-streaming-response-examples/blob/master/src/main/scala/com/experiments/calvin/ws/WebSocketRoutes.scala
This ticket is very old by now. I think we missed asking for a clarification in the beginning that would anyone allow to work on this as it is unclear what is broken exactly and in which context. Judging by the number of :+1:s it seems that something is still amiss for some people. I suspect the main reason this ticket gathered followers is that it is vague enough to fit different kinds of issues that people have.
I tend to closing this particular ticket and follow it up with better ones that provide reproducible test cases for unexpected behaviors. If you are interested in this ticket and are unsure whether to open up a new ticket please feel free to add comments here, describing the issue you are seeing.
Most helpful comment
Any news?