marc0s
Hi,
I’m learning elixir and the current use case I’m now playing with is a websocket server with plug_cowboy and a client with websockex. Server is working nice if I test with websocat or other clients.
My main issue is that while coding a simple test case where the client sends a message and the test finishes (ends the process, as I understand, which may be wrong) before actually receiving the response. I suspect I’m missing some kind of loop that keeps reading the socket for incoming messages instead of just sending a message and finishing the process [because no more code is left to be run].
My code is as follows, test client first:
use WebSockex
require Logger
def start(url, state) do
WebSockex.start(url, __MODULE__, state)
end
def request(client, message) do
Logger.info("Sending request: #{inspect message}")
WebSockex.send_frame(client, {:text, message})
end
def handle_connect(_conn, state) do
Logger.info("Connected")
{:ok, state}
end
def handle_frame({:text, msg}, state) do
Logger.info "Received a message: #{inspect msg}"
{:ok, state}
end
def handle_cast({:send, {type, msg} = frame}, state) do
IO.puts "Sending #{type} frame with payload #{inspect msg}"
{:reply, frame, state}
end
def terminate(_reason, _state) do
IO.puts("terminate")
exit(:normal)
end
end
And the test:
{:ok, pid} = Client.start("ws://localhost:4444/", %{})
Client.request(pid, Jason.encode!(%{msg: "hi there"}))
# something missing here to keep Client connected and later call Client.stop
end
Thanks in advance!
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 4- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
alvises
If I understood correctly, you have a local websocket server, made with cowboy and plug_cowboy. After you call
Client.request/2, you expect that the client receives a websocket frame from the server right? What exactly do you want to test, which assertion?marc0s
(Currently) The server is just an echo server, so I want to assert in the test that the server sent back the same the client sent first. By looking at the server logs, the message is received and replied, but (coming from other languages) client side I’d expect the client to remain connected to the websocket and see how the reply is logged,at least to stdout
I’m probably missing something very basic here, to the extent that my problem may not be understood. Please ask me to clarify whatever makes no sense!
Thanks.
alvises
The
Clientis asynchronous, so when you make arequest/2the process of that test ends without waiting for any answer, bringing everything down (and closing the connection). So, the quickest way to see the log, to see if your experiment works, is to useiex(the elixir interactive console) and start the client there.If you really need to make a real unit test, the frames the
Clientreceives from the server are internal. You shouldn’t test directly those messages, instead I would test the client’s interface.Ok, so let’s say you want to keep everything asynchronous and, as part of the implementation of your Client, you want that the client forwards to a process each websocket frame:
When you start the client, you pass
self(), which is the test process pid. When the client process receives a websocket frame, it sends a message tosend_to_pid. Withassert_receivethe test waits that the message is received.As you can see in
handle_frame/2, the client sends also its pid (self()) as part of the message. In this way we can pattern match it withassert_receiveto be sure that the pid is the same of the client we started.PS: use
start_linkso what you spawn is a linked process. In this way when test exists it brings down your client process.marc0s
Thank you so much for the detailed explanation. Really appreciated
I got it working with your indications. Still need to grasp what seems to me the “all is a process” motto and so I need to be sending messages all along to interact with the different elements.
Best regards.