-
Notifications
You must be signed in to change notification settings - Fork 596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
User API for websocket close with code and reason #2458
Comments
Would be nice to support that. Any idea how we put that in the API? We currently don't have a side-channel where we could put that information. I guess, we could either
|
Without grasping all consequences I think a subtype of |
I am 100% in favor of this. We definitely need this for our use case. We have been working around it for quite some time. For reference, I posted this on Stack Overflow almost a year ago with no answers: https://stackoverflow.com/questions/50932959/how-to-get-websocket-close-code-from-akka-http |
Good to have validation 'from the real world' here! Would you be interested in preparing a PR? |
So actually it isn't possible to close the websocket session and set a close code and reason? |
Any updates on this? I have a use case where I want to accept only one WebSocket for one particular URL. If there's another request for the same URL, I want to reject that. Right now, I'm rejecting with HTTP 412 error code, but it seems that that error code is not available in javascript code. This stackoverflow question describes a similar problem: The recommendation from the accepted answer is to accept the websocket and immediately close it with an application-specific error code and error message. I understand that it's not an implemented feature as of now, but is there any workaround available to achieve that? |
I'd also need this for a compliant implementation of a GraphQL over Websocket protocol; I am happy to submit a pull request, but I'd appreciate some direction about the proper way to implement this, @jrudolph I tend to favour a custom exception. Adding a new message subtype would perhaps break binary compatibility, whereas an exception would likely not change much to existing users, and it would clarify that the websocket stream definitely ended, wheras a message subtype could convey the idea that the websocket will remain alive. An exception would also work in both directions: If the client closes the connection with a code Akka can throw the exception in the websocket stream and downstream consumer can handle it via |
One problem might be that failures in a stream will discard buffers, so it cannot be easily guaranteed that all messages have been sent before the close. As long as we don't have good ideas whether that is the right thing to do, I'm still more interested in alternatives. One other alternative could be to use specially crafted messages for this purpose. E.g. we could hide something in a streamed message by crafting a special kind of It's a bit hacky but maybe the best solution given the constraints? |
If the client closes the connection do server-side buffers still matter? If not we could use a hybrid approach: Throw an exception for client-side closes, and use a custom message for server-side closing. This would change the Flow type to e.g. The exception wouldn't break anything I believe; attempting to talk to a closed socket likely already throwns some other exception at some point. Another outgoing message variant is perhaps also fine; I don't remember the variance of |
No, it's about buffers (implementation or user) in the stream that sends the close after the component that throws the failure. E.g. if this user wants to close with code: Flow[Message]
.map { peerCmd =>
if (cond) throw CloseNowException(code, reason)
}
.buffer(...) // or filter or mapAsync, etc. In that case, anything behind the component that closes the connection might discard buffered data. Of course, you could document that for the user and require the user to make sure to buffer nothing. Then we would need to check our internals as well that we avoid losing data if possible. Still it makes it somewhat awkward if you want to do a (non-abort) regular close with a custom code. I just looked again in the RFC as well, and it's not clear to me if there's a clear difference between "regular close with code" and "connection abort with code" and whether we would need to support both. |
@jrudolph I understand, but if we use a regular message for a server-side close buffering wouldn't be an issue, would it? The close message would be buffered just like a normal text or binary message after all. So if we used an exception for a client side close, and a regular message for a server side close, as suggested in my previous, we'd be fine, wouldn't we? The server could then do a regular close by just sending the close message regularly through the flow, including any buffering, or a abort which discards any buffers, by throwing a custom exception and then ultimately recovering with a Close message. Client side closes would still always discard any buffers in the stream; but if the client's gone any buffers in the flow are lost anyway, since there's none left send their contents to. |
Not sure I get the distinction between server and client here. Both could be implemented with akka-http and on both sides you might be interested in only closing the connection after all buffered messages have been sent. |
I am sorry for the confusion; I was speaking from the perspective of an Akka HTTP server talking to another client because that's our use case. I'll try to rephrase what I said in terms of sources and sinks representing the websocket stream: If the remote end connected to a To let Akka HTTP close the websocket with a code on its own it could send a new Does this illustrate what I'm thinking about? As said I'm would make a pull request in that direction, but since it's not a trivial thing I'd like to be sure of the direction to go into. |
Any updates on this? I am stuck at an use case where connection should be closed after some time,based on time, token etc. |
To comment on the above suggestion to use an exception, I am not sure if that is the best approach. Closing of the web socket does not indicate an exceptional case. Closing is a normal part of the lifecycle. Once could argue that a close code other than 1000 could represent an exceptional case. In this way, you could argue that a normal close frame of 1000 would not generate the exception and any other close code would. However, even with the 1000 code case, there is a human readable reason that is part of the protocol that we could like access too. In our use case for example, (on the server side) we would like to be able to distinguish code 1000 from code 1001. Neither of these are exceptional or error cases. The former indicates that the web socket was normally closed, the other indicates that the page is being navigated away from. In addition codes 4000-4999 are available for applications to use. These codes do not indicate that there has been an error of any kind, so handling them via an exception / recover would give the wrong connotation in my opinion. |
A web socket connection can be closed with an application level status code (4000-4999) see https://tools.ietf.org/html/rfc6455#section-7.4 but we have no user level API for this in Akka HTTP.
The text was updated successfully, but these errors were encountered: