Azolo

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

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 name option 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 :gen module 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 try and 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_debug for 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/4 callback
  • there’s an additional format_status/2 callback you can implement to control what information is returned on :sys.get_status and :sys.get_state used, for example, by observer.
Azolo

Azolo

WebSockex 0.4.1 Released!

Enhancements

  • Allow :via and :global tuples for named registration.
    • This includes handling for cast/2 and send_frame/2.
  • Add access to response headers during handle_connect/2 via Conn.resp_headers.
  • Add Conn.parse_url/1 to handle url to URI conversion.
  • Allow Conn.new/2 to use a url string instead of a URI struct.
  • Automatically add a “/” path to a pathless url.
    • The HTTP request will break without a valid path!
  • Add child_spec definitions for Elixir 1.5+
    • Or any version that exports Supervisor.child_spec/2
  • Some documentation tweaks

Bug Fixes

  • No longer invoke handle_disconnect if 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/2 in a callback.

Take a look at the v0.4.0...v0.4.1 diff or the release on hex.pm for more information.

sasajuric

sasajuric

Author of Elixir In Action

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

Azolo

WebSockex 0.3.0 Released!

Breaking Changes

  • The parameters for the handle_connect/2 callback have been reversed. The order is now (conn, state).

Enhancements

  • Added initial connection timeouts. (:socket_connect_timeout and :socket_recv_timeout)
    • Can be used as start or start_link option or as a Conn.new option.
    • :socket_connect_timeout - The timeout for opening a TCP connection.
    • :socket_recv_timeout - The timeout for receiving a HTTP response header.
  • start and start_link can now take a Conn struct 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_state functions.
    • These are undocumented, but are meant primarily for debugging.

Bug Fixes

  • Ensure terminate/2 callback is called consistently.
  • Ensure when termination when a parent exit signal is received.
  • Add the system_code_change function so that the code_change callback 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

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/2 is now synchronous and returns an error when connection is opening or closing.

Enhancements

  • Added debug printing for the :sys module.
  • Rework Conn.new to accept other protocols.
  • Added an InvalidFrameError for frames unrecognized by Frame.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 1011 when there is an unexpected error. (Like an Exception in the middle of a callback)
  • Add a more specific error when the :websockex application hasn’t been started yet.
  • Added a :name options 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

Where Next?

Popular in Libraries Top

marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New
treble37
Just looking for a little feedback on a tiny helper library I built - Sometimes I find the need to convert maps with atom keys to maps...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
mbuhot
Leverage Open Api 3.0 (Swagger) to document, test, validate and explore your Plug and Phoenix APIs. Generate and serve a JSON Open API ...
New
mcrumm
If you would like to migrate away from node/npm/webpack while still using sass, the dart_sass package provides a installer and runner for...
New
michalmuskala
Hello everybody. I have just released Jason - a new JSON library. You might be wondering, why do we need a new library? The primary foc...
New
wfgilman
I’ve cleaned up and open sourced three financial libraries I was using for my company. They are bindings for the APIs of these three comp...
New
tmbb
PhoenixWS - Websockets over Phoenix Channels Source code on Github here: https://github.com/tmbb/phoenix_ws Phoenix channels are a great...
New
gabrielpoca
Hello everyone! I want to share with you something that I’m really proud of: https://stillstatic.io/ Still is a static site builder for...
New
mtrudel
Bandit is an HTTP server for Plug and WebSock apps. Bandit is written entirely in Elixir and is built atop Thousand Island. It can serve...
New

Other popular topics Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Sub Categories:

We're in Beta

About us Mission Statement