A WebSocket client build on top of Mint.WebSocket.
- Reconnects with backoff
- Use
Minch.backoff/2to calculate an exponential backoff duration.
- Use
- Handling control frames
- Closes the connection after receiving a
:closeframe. - Replies to server pings automatically.
- Closes the connection after receiving a
The package can be installed by adding minch to your list of dependencies in mix.exs:
defdepsdo[{:minch,"~> 0.2.1"}]enddefmoduleEchoClientdouseMinch@impltruedefconnect(state)dostate.urlend@impltruedefhandle_frame(frame,state)doIO.inspect(frame){:ok,state}endend{:ok,pid}=Minch.start_link(EchoClient,%{url: "wss://ws.postman-echo.com/raw"})Minch.send_frame(pid,:ping)defmoduleEchoClientdouseMinchrequireLoggerdefstart_link(init_arg)doMinch.start_link(__MODULE__,init_arg,name: __MODULE__)end@impltruedefinit(_init_arg)do{:ok,%{connected?: false}}end@impltruedefconnect(_state)dourl="wss://ws.postman-echo.com/raw"headers=[{"authorization","bearer: example"}]# don't do this in productionoptions=[transport_opts: [{:verify,:verify_none}]]{url,headers,options}end@impltruedefhandle_connect(_response,state)doLogger.info("connected")Process.send_after(self(),:produce,5000){:reply,{:text,"welcome"},%{state|connected?: true}}end@impltruedefhandle_disconnect(reason,attempt,state)doLogger.warning("disconnected: #{inspect(reason)}"){:reconnect,Minch.backoff(attempt),%{state|connected?: false}}end@impltruedefhandle_info(:produce,state)doProcess.send_after(self(),:produce,5000){:reply,{:text,DateTime.utc_now()|>DateTime.to_iso8601()},state}end@impltruedefhandle_frame(frame,state)doLogger.info(inspect(frame)){:ok,state}endendurl="wss://ws.postman-echo.com/raw"headers=[]# don't do this in productionoptions=[transport_opts: [{:verify,:verify_none}]]IO.puts("checking ping to #{url}...")caseMinch.connect(url,headers,options)do{:ok,pid,ref}->Minch.send_frame(pid,{:text,to_string(System.monotonic_time())})caseMinch.receive_frame(ref,5000)do{:text,start}->ping=System.convert_time_unit(System.monotonic_time()-String.to_integer(start),:native,:millisecond)IO.puts("#{ping}ms"):timeout->IO.puts("timeout")endMinch.close(pid){:error,error}->IO.puts("connection error: #{inspect(error)}")end