Azolo
WebSockex - An Elixir WebSocket client
Hey everyone,
I just released WebSockex which is a Elixir WebSocket client.
WebSockex strives to work as a OTP special process, be RFC6455 compliant, and be simple to use by providing smart defaults for common actions.
Take a look and let me know about any questions, suggestions, or any other comments you may have,
Most Liked
michalmuskala
The remark that it implements special process by hand made me interested, so I had a look at the code. Here are some things I spotted, I hope you don’t mind.
- you don’t handle the regular naming conventions - it would be nice to be able to pass the
nameoption like with all the Elixir’s stdlib behaviours. When you do this, there are some race conditions to consider, so I would advise looking at using the:genmodule that powers all the Erlang behaviours (it’s not documented publicly, but I saw many projects using it, I’m not sure how bad of an idea that is - but it definitely handles a lot of common scenarios). - whenever you call user module callbacks, they should be wrapped in a
tryand errors should be handled appropriately (e.g. you want to call the terminate callback in that case before dying). - it’s nice to use
:sys.handle_debugfor any messages received and sent out (or any “major” events that happen in a process) - this is really useful when things go wrong. - in the receive loop, you probably want to look for the
{:EXIT, parent, reason}message in case the user starts trapping exits in the process. The special process has to exit with the same reason as the parent in case that happens. - it looks like you don’t implement the
system_code_change/4callback - there’s an additional
format_status/2callback you can implement to control what information is returned on:sys.get_statusand:sys.get_stateused, for example, by observer.
Azolo
WebSockex 0.4.1 Released!
Enhancements
- Allow
:viaand:globaltuples for named registration.- This includes handling for
cast/2andsend_frame/2.
- This includes handling for
- Add access to response headers during
handle_connect/2viaConn.resp_headers. - Add
Conn.parse_url/1to handle url to URI conversion. - Allow
Conn.new/2to use a url string instead of aURIstruct. - Automatically add a “/” path to a pathless url.
- The HTTP request will break without a valid path!
- Add
child_specdefinitions for Elixir 1.5+- Or any version that exports
Supervisor.child_spec/2
- Or any version that exports
- Some documentation tweaks
Bug Fixes
- No longer invoke
handle_disconnectif there is reason to exit from invoking a callback. (e.g. an exception was raised) - Properly handle unexpected SSL socket termination.
- This seems pretty important, but I don’t know…
- Return a descriptive error when trying to use
send_frame/2in a callback.
Take a look at the v0.4.0...v0.4.1 diff or the release on hex.pm for more information.
sasajuric
I absolutely appreciate and encourage trying different things, and even overcomplicating the code for the purpose of learning and gaining a deeper understanding. That being said, if learning is the only motivation for using your own special process here, and assuming that this library is meant to be used by others and contributed to, I think it might be wise to switch to GenServer. Doing this would make it easier to solve (and in some cases automatically solve) issues mentioned by @michalmuskala.
It might also simplify some future additions. For example, I think that calls should be supported as well, and this would be pretty simple if the process was a GenServer. Making the interface of your behaviour more similar to GenServer by supporting timeouts and hibernate options in return tuples, as well as stop option would also be nice. Again, this should be fairly trivial if your behaviour was powered by GenServer.
I have similar sentiments about the current state of WS clients. About a year ago, I looked into a couple of them, and wasn’t really completely pleased with any. In the end, I settled for this branch. I like that your project starts with a clean slate, and has good test coverage. That seems very promising!
Azolo
WebSockex 0.3.0 Released!
Breaking Changes
- The parameters for the
handle_connect/2callback have been reversed. The order is now(conn, state).
Enhancements
- Added initial connection timeouts. (
:socket_connect_timeoutand:socket_recv_timeout)- Can be used as
startorstart_linkoption or as aConn.newoption. -
:socket_connect_timeout- The timeout for opening a TCP connection. -
:socket_recv_timeout- The timeout for receiving a HTTP response header.
- Can be used as
-
startandstart_linkcan now take aConnstruct in place of a url. - Added the ability to handle system messages while opening a connection.
- Added the ability to handle parent exit messages while opening a connection.
- Improve
:sys.get_status,:sys.get_state,:sys.replace_statefunctions.- These are undocumented, but are meant primarily for debugging.
Bug Fixes
- Ensure
terminate/2callback is called consistently. - Ensure when termination when a parent exit signal is received.
- Add the
system_code_changefunction so that thecode_changecallback is actually used.
Take a look at the v0.2.0..v0.3.0 diff or the release on hex.pm for more information.
Azolo
WebSockex 0.4.0 Released!
Just as a side note, I think the most exciting thing about this release is the addition of OTP based debugging capabilities. The debug messages themselves are useful but not perfect. If you would like more hooks or better output feel free to open an issue.
Breaking Changes
-
send_frame/2is now synchronous and returns an error when connection is opening or closing.
Enhancements
- Added debug printing for the
:sysmodule. - Rework
Conn.newto accept other protocols. - Added an
InvalidFrameErrorfor frames unrecognized byFrame.encode_frame. - Go through the disconnect cycle when there’s an error while with the
{:reply, frame, state}callback response. - Send a close frame with the close code
1011when there is an unexpected error. (Like anExceptionin the middle of a callback) - Add a more specific error when the
:websockexapplication hasn’t been started yet. - Added a
:nameoptions for local registration.
Bug Fixes
- Fix a couple of places where the call stack wasn’t being properly tail-call optimized.-
Take a look at the v0.3.1...v0.4.0 diff or the release on hex.pm for more information







