I am connecting some client desktop applications to my server using GenSocketClient. I need to obtain the IP address for the client, which I use to identify clients (the whole system is in a private network with static IP addresses). In a channel, our state is a socket which does not have this info. It does live in the Conn and in the cowboy_websocket
process’ state. I was able to find the websocket connection details in req
of the state kept in cowboy_websocket.erl and extracted it like so:
defmodule MyAppWeb.SomeChannel do
Record.defrecord(:state, Record.extract(:state, from: "deps/cowboy/src/cowboy_websocket.erl"))
def handle_in("ping", payload, socket) do
{cowboy_websocket_state, _, _} = :sys.get_state(socket.transport_pid)
true = Record.is_record(cowboy_websocket_state, :state)
req = Keyword.fetch!(state(cowboy_websocket_state), :req)
peer = req[:peer]
{:reply, {:ok, payload}, socket}
end
end
It was suggested that this method is “hacky”, which is not untrue, and that I raise an issue with regards to getting the peer
from the req
, which becomes the remote_ip
in the conn
into the socket
.
So, I have modified connect
in Phoenix.Transports.WebSocket
to put conn.remote_ip
into my socket’s private
map. I couldn’t see a way to request this from the cowboy websocket process and there is an old issue where the author informs them they have to put it in their state in init
.
Any advice?