Stop a websocket connection

I am implementing a websocket purely using elixir and cowboy. How can i close a websocket connection in the websocket_init/1 function? I want to send a reason to close the connection and then pattern match it in the terminate/3 function, so that i can do some other functions inside it.

def websocket_init(state) do
    info("Initializing connection")
    case Account.get_user(state.id) do
      %User{} ->
        {:ok, state}
      nil ->
        {:error, "No account"}
    end
  end

So that in the terminate/3 function I can do something like this:

def terminate({:error, "No account"}, _req, _state) do
    info("No account")
    :ok
  end

def terminate(_reason, _req, _state) do
   info("Terminating connection")
   :ok
end

Try {:stop, "state"} (https://github.com/ninenines/cowboy/blob/db0d6f8d254f2cc01bd458dc41969e0b96991cc3/src/cowboy_websocket.erl#L560) which will invoke the terminate callback (https://github.com/ninenines/cowboy/blob/db0d6f8d254f2cc01bd458dc41969e0b96991cc3/src/cowboy_websocket.erl#L655)

websocket_init must return a CallResult type, defined on https://ninenines.eu/docs/en/cowboy/2.2/manual/cowboy_websocket/

I haven’t tested this myself, but just reading through the source code. This could be incorrect.

{:stop, state} works. But the reason in terminate/3 function is same as a normal connection closing. I want it to be different, so that I can pattern match it as shown above

Can you include that in the state? It looks like it’s passed through to the terminate call from your stop tuple—if I’m reading this right.

Yes. I tried including the reason in the state and now I can pattern match the state and there by do what ever it is that I want.

Thanks man. I was too concentrated on the reason argument of the terminate/3 function that I didn’t look in to other option. Thanks again :slightly_smiling_face: :heart:

1 Like