gun:ws_upgrade(ConnPid, "/websocket").
This chapter describes how to use the Gun client for communicating with a Websocket server.
Websocket is a protocol built on top of HTTP. To use Websocket, you must first request for the connection to be upgraded. Only HTTP/1.1 connections can be upgraded to Websocket, so you might need to restrict the protocol to HTTP/1.1 if you are planning to use Websocket over TLS.
You must use the gun:ws_upgrade/2,3,4 function to upgrade to Websocket. This function can be called anytime after connection, so you can send HTTP requests before upgrading to Websocket.
gun:ws_upgrade(ConnPid, "/websocket").
Gun will set all the necessary headers for performing the Websocket upgrade, but you can specify additional headers if needed. For example you can request a custom sub-protocol.
gun:ws_upgrade(ConnPid, "/websocket", [
{<<"sec-websocket-protocol">>, "mychat"}
]).
You can pass the Websocket options as part of the gun:open/2,3 call when opening the connection, or using the gun:ws_upgrade/4. The fourth argument is those same options.
When the upgrade succeeds, a gun_upgrade message is sent. If the server does not understand Websocket or refused the upgrade, a gun_response message is sent. If Gun couldn't perform the upgrade due to an error (for example attempting to upgrade to Websocket on an HTTP/1.0 connection) then a gun_error message is sent.
When the server does not understand Websocket, it may send a meaningful response which should be processed. In the following example we however ignore it:
receive
{gun_upgrade, ConnPid, StreamRef, [<<"websocket">>], Headers} ->
upgrade_success(ConnPid, StreamRef);
{gun_response, ConnPid, _, _, Status, Headers} ->
exit({ws_upgrade_failed, Status, Headers});
{gun_error, ConnPid, StreamRef, Reason} ->
exit({ws_upgrade_failed, Reason})
%% More clauses here as needed.
after 1000 ->
exit(timeout)
end.
Once the Websocket upgrade has completed successfully, you no longer have access to functions for performing requests. You can only send and receive Websocket messages.
Use gun:ws_send/2 to send messages to the server.
gun:ws_send(ConnPid, {text, "Hello!"}).
Note that if you send a close frame, Gun will close the connection cleanly but will attempt to reconnect afterwards.
Gun sends an Erlang message to the owner process for every Websocket message it receives.
receive
{gun_ws, ConnPid, StreamRef, Frame} ->
handle_frame(ConnPid, StreamRef, Frame)
end.
Donate to Loïc Hoguin because his work on Cowboy, Ranch, Gun and Erlang.mk is fantastic:
Recurring payment options are also available via GitHub Sponsors. These funds are used to cover the recurring expenses like food, dedicated servers or domain names.