Current section
Files
Jump to
Current section
Files
lib/chaperon/action/websocket/connect.ex
defmodule Chaperon.Action.WebSocket.Connect do
@moduledoc """
WebSocket connection action that needs to be run in order for a
`Chaperon.Session` to be successfully connected to a web server via WebSocket.
Assigns `websocket` and `websocket_url` values to a session when run,
which are used by the remaining websocket actions found under
`Chaperon.Action.WebSocket`.
The stored values are accessible via `session.assigned.websocket` &
`session.assigned.websocket_url`.
"""
defstruct [
path: nil,
options: []
]
def url(action, session) do
case Chaperon.Action.HTTP.url(action, session) do
"https" <> rest ->
"wss" <> rest
"http" <> rest ->
"ws" <> rest
("ws" <> _) = ws_url ->
ws_url
end
end
end
defimpl Chaperon.Actionable, for: Chaperon.Action.WebSocket.Connect do
alias Chaperon.Session
alias Chaperon.Action.WebSocket
alias Chaperon.Action.WebSocket.Connect
use Chaperon.Session.Logging
def run(action, session) do
ws_url = Connect.url(action, session)
session
|> log_info("WS_CONN #{ws_url}")
timeout = Session.timeout(session)
async_connect(session, ws_url)
receive do
{:ws_connected, ws_client, ^ws_url} ->
session
|> WebSocket.assign_for_action(action, ws_client, ws_url)
|> Session.ok
after timeout ->
session
|> log_info("Timeout while connecting via WS to #{ws_url}")
|> Session.error({:timeout, :ws_conn, ws_url, timeout})
end
end
def abort(action, session) do
{:ok, action, session}
end
def async_connect(session, ws_url) do
parent = self()
spawn_link fn ->
{:ok, ws_client} = WebSocket.Client.start_link(session, ws_url)
send parent, {:ws_connected, ws_client, ws_url}
end
end
end
defimpl String.Chars, for: Chaperon.Action.WebSocket.Connect do
def to_string(%{path: path}),
do: "WS Connect[#{path}]"
end