ActionCable: allow to pass websocket.close args#51043
ActionCable: allow to pass websocket.close args#51043rafaelfranca merged 3 commits intorails:mainfrom
Conversation
|
|
||
| def close | ||
| websocket.close | ||
| def close(code = nil, reason = nil) |
There was a problem hiding this comment.
This is an internal method, we do not expose it anywhere.
Thus, I'd suggest to hack around Connection#close in your codebase instead.
There was a problem hiding this comment.
I think this is OK because:
- According to the implementation, the
@websocketcan only beClientSocket - This class is a wrapper, and my patch is just adding the missing args
Could you give me some hints on how to hack Connection#close to customize the code and reason?
There was a problem hiding this comment.
With this change, you still need to access internals, e.g., self.websocket.close(code, reason), but you can already do this via self.websocket.websocket.close(code, reason).
Could you give me some hints on how to hack Connection#close to customize the code and reason?
Smth like:
def close(ws_code: nil, ws_reason: nil, **)
return websocket.close(ws_code, ws_reason) if ws_code
super(**)
end
# and then
connection.close(ws_code: 1001, ws_reason: "whatever")There was a problem hiding this comment.
I don't mean to change the Connection#close interface.
I can override the Connection#close method with my change.
class MyConnection < ActionCable::Connection::Base
def close
code = 1001 # Determine which code should return
websocket.close(code)
end
endThere was a problem hiding this comment.
In your code
def close(ws_code: nil, ws_reason: nil, **)
return websocket.close(ws_code, ws_reason) if ws_code
super(**)
endMy patch is actually made this line websocket.close(ws_code, ws_reason) work.
The real websocket object allows passing code and reason on close,
it is wrapped by the ActionCable::Connection::WebSocket (the websocket instance variable in the Connection class), which doesn't expose the ability, I'm adding it.
|
This class isn't public API of the framework so it doesn't make much sense to add options so you can use in your application or library. This class should not be used in application or library because it isn't public. Now, if this class should be private is another discussion. I'm not so sure. If we expect people to be interacting with that object it should not be. What reasons someone have to interact with this object? |
Returns a code, and a reason is WebSocket standard Spec MDN In my case, I'm extending ActionCable to add auto disconnect behavior if the client is idle long enough. The server side can give a clear reason to distinguish would be great. ActionCable now always returns code |
Then you should rely on Action Cable protocol here, i.e., send Using Action Cable implies following its conventions; if you want to support non-Action Cable-complient clients, you should use a custom connection class and implement your logic there.
And this discussion happens in #50979 🙂 (tl;dr it should not; we should avoid making Connection/Channel classes dependent on the underlying transport mechanism) |
If I implement my own In your PR, I replied I'm working on a PoC that implements the NoStr protocol based on the ActionCable |
For WebSockets, yes (and not widely used — that's why build custom protocols on top of them). I'd prefer to avoid coupling high-level Action Cable concepts with transport implementations. (But I'm not the one making decisions here; at least, yet, right, @rafaelfranca 😁?). Anyway, the proposed change would allow to avoid the following hacking (kinda summary for those who might join the discussion and me thinking out load): websocket.send(:websocket).close(code, reason)And instead have: websocket.close(code, reason)The Since we name the wrapper object a "websocket", it sounds reasonable to support the def close(...)
websocket.close(...)
end |
If decision are well based like this one, I'm glad that you are trying to make it. It seems we should expose that websocket object. I agree we should be using the |
08ef21e to
d5786b2
Compare
Changed, and I also refactored |
This PR allows you to set
codeandreasonwhen closing a WebSocket connection.It's very useful when hacking ActionCable.
In addition, I small refactor the file to avoid potential nil error, I can remove this change.
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]