-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
WebSocket API Review #2902
Comments
|
Leaning more and more towards a no on 7. A |
I’ve got a different approach on 7. A But a The type system consequences are super interesting. If you’re building a chat app you need a little state machine to move messages from the user to the websocket. Presumably this is tough work because you need to keep track everything until it has been acknowledged. But do you want to enqueue messages before the websocket is open? Maybe? And for us do we want to optimistically transmit such messages? I’m flexible on this but I think it’s probably the most interesting API we’ve seen in a long time. |
Answered without looking at other answers at all (to get that natural reaction)...
|
Yep. The spec mandates this so it will always be the behavior. |
Another thing about the Trello sockets - once you're connected to sockets (general), we then send messages which subscribe us to individual channels (specific). E.g., there's a channel for your current user or a channel for a board you might have open. Those channel subscription messages currently have to be queued and then sent once But the way the subscription works we have to track our request and then match it with a later response. So it'd be difficult to wrangle if we thought we sent a subscription request but it never actually got sent. |
I wonder what it’d look like to hook up Tape to WebSockets. It’d get pretty involved due to a missing link between messages sent and messages received. With a Request/Response model, you know your request was accepted when you receive a 2xx response. With WebSockets, you must devise your own application-layer scheme to acknowledge which messages were accepted. Ugly. |
WebSockets don't seems appropriate for that use case. If you want a request/response model then you should be using http/2 or at worst a keep-alive connection and definitely not web sockets. |
The API looks pretty good but I think some of the semantics around building a reliable sender and receiver were a little tricky. It seems like the API handles reading the socket in it's own thread then sends messages to the |
I'm not convinced this is true. Proper shutdown happens in only two ways:
Improper shutdown also happens in two ways, except if you handle the proper shutdown case correctly these come for free:
If the listener receives So this really boils down to one thing: That leads me to
The API would be more simple, but it wouldn't be easier to use. In this queued write system how do you know which write failed? What happens to queued data that wasn't written? What do we do with queued data when the listener receives If we adopted a queued system the writing API would not change at all, but we'd now need to add APIs to support all these cases:
This actually makes the API more complex and makes writing a correct client more difficult. Your application requirements have to reconcile the assumptions that we've made about how you want to write to web sockets and they won't always match. Web sockets are complicated to implement and we do force you to make decisions at the application layer. How you want to handle queueing, successful message sends, and retrying the connection is hard to implement inside the library to appease everyone. |
I think we need |
Thanks, for the details. As for cleanup, I think I managed to get most of what you described covered in my client implementation (I just wasn't sure this was all I needed). Having the process you described above saved in some of the more permanent documentation would be nice. You've made a convincing argument that management of the write side should be left to the implementer. What struck me as strange about the API is that an established websocket connection is a symmetric pipe, but the API interface is asymmetric (one where the read side appears managed and the write is not). Wouldn't many of the same arguments about more nuanced management apply to the read side as well? I like the |
Currently it just prints WebSockets messages as they arrive, never sending any. In a follow-up I'd like to do that, and also start to use this to figure out where and how our WebSockets client can be improved. #2902
Currently it just prints WebSockets messages as they arrive, never sending any. In a follow-up I'd like to do that, and also start to use this to figure out where and how our WebSockets client can be improved. #2902
After writing a little experiment code some observations:
|
Currently it just prints WebSockets messages as they arrive, never sending any. In a follow-up I'd like to do that, and also start to use this to figure out where and how our WebSockets client can be improved. #2902
I propose we always fully buffer WebSocket messages. The consequences:
I’m proposing this behavior even though I know it’s weird. The reason is that message receipts are the application layer’s concern. If the client sends something that’s intended to be durable, the client already needs to hold that thing until a receipt is received. Blocking until the bytes have been written to the socket doesn’t confirm anything. |
Currently this uses a placholder name, NewWebSocket. I'd like to get this reviewed, expand it to cover MockWebServer's needs, and then I'll delete the current blocking API. Still undecided is which APIs to add - if any - to expose the state of the web socket. #2902
Currently this uses a placholder name, NewWebSocket. I'd like to get this reviewed, expand it to cover MockWebServer's needs, and then I'll delete the current blocking API. Still undecided is which APIs to add - if any - to expose the state of the web socket. #2902
Currently this uses a placholder name, NewWebSocket. I'd like to get this reviewed, expand it to cover MockWebServer's needs, and then I'll delete the current blocking API. Still undecided is which APIs to add - if any - to expose the state of the web socket. #2902
I’m happy with where this is now. |
I still think most people are going to end up writing code to keep track of the state of the websocket in a way that could be provided by the API itself because of this problem. |
yeah, for sure. I think I’d like to write a sample to exercise that case, which may motivate expanding the API. |
For 5: I would like to expose the ping pong api.Because this is very helpful to keep your websocket connected and reconnect when meet with network issue or something else.The WebSocketListener onClose method isn't reliable in practice. |
I went through the WebSocket API and wrote down my thoughts. Nothing too earth-shattering, just some ideas.
maxRequestsPerHost
? (I think yes, but we should explicitly call this out.)WebSocket#close()
?isCanceled()
return true after a WebSocket is closed?Do we throw an IllegalStateException if you write the socket inForbid writes from reader thread. #2905onOpen()
? What aboutsendPing()
andclose()
?WebSocketListener
. WithCall
we haveCallback
and the names are cute. IsWebSocketCallback
terrible?WebSocketCall
andWebSocket
types? I’m getting here via the (slight) redundancy betweencancel()
andclose()
. ObviouslysendMessage()
would need to be a bit more clever to do something reasonable if it were invoked beforeonOpen()
is received. Though it’s interesting to think about “fast open” where a web socket client can enqueue messages before we have confirmation that it’s all going to connect.Should it beRemove inconsistent 'send' prefix from message/ping methods. #2904sendMessage(RequestBody)
or justsend(RequestBody)
or justmessage(RequestMessage)
? Maybe instead ofsendPing(ByteString)
it should be justping(ByteString)
or evenping()
?The text was updated successfully, but these errors were encountered: