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 authenticate.
gun:ws_upgrade(ConnPid, "/websocket", [ {<<"authorization">>, "Basic dXNlcm5hbWU6cGFzc3dvcmQ="} ]).
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.
Gun can negotiate the protocol to be used for the Websocket connection. The protocols
option can be given with a list of protocols accepted and the corresponding handler module. Note that the interface for handler modules is currently undocumented and must be set to gun_ws_h
.
gun:ws_upgrade(ConnPid, "/websocket", [] #{protocols => [{<<"xmpp">>, gun_ws_h}]}).
The upgrade will fail if the server cannot satisfy the protocol negotiation.
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.