Failing to run basic gun ws connection

I am trying to connect to a websocket with “gun”. As far as I understand the workflow is the following:

  1. {ok, ConnPid} = gun:open(host, port).
  2. {ok, _protocols} = gun:await_up(ConnPid}.
  3. StramRef = gun:ws_upgrade(ConnPid).

I am getting some weird handshake errors.
I followed advice from this post (Working config for gun websocket client - Guides/Tuts/Tips/Info - Elixir Programming Language Forum) with no success

I am trying to connect to this ws: wss://stream.bybit.com/v5/public/spot

please help :slight_smile:

Please post what error you are getting.

Anyway, please see this post, maybe it can help you.
The post’s example has the three steps you mentioned, see here.

thanks got you response.

I am trying to a “well-known” host and expect this to “just work”.
when I do this {ok, C} = gun:open("stream.bybit.com", 443, #{trace => true}).
then among trace messages I see this

(<0.270.0>) returned from gun:normal_tls_handshake/4 -> {error,
                                                         {options,
                                                          incompatible,
                                                          [{verify,
                                                            verify_peer},
                                                           {cacerts,
                                                            undefined}]},
                                                         {state,<0.260.0>,
                                                          {up,
                                                           #Ref<0.1409967944.4169138179.104785>},
                                                          "stream.bybit.com",
                                                          443,<<"https">>,
                                                          "stream.bybit.com",
                                                          443,[],
                                                          #{trace => true},
                                                          undefined,undefined,
                                                          gun_tls,true,
                                                          {ssl,ssl_closed,
                                                           ssl_error},
                                                          undefined,undefined,
                                                          undefined,
                                                          gun_default_event_h,
                                                          undefined}} (Timestamp: {1714,
                                                                                   799752,
                                                                                   553756})

but if I specify additionally cacerts (gun:open("stream.bybit.com", 443, #{trace => true, tls_opts => [{cacerts, certifi:cacerts()}]}).) then I get

=NOTICE REPORT==== 4-May-2024::08:25:08.916337 ===
TLS client: In state wait_cert_cr at ssl_handshake.erl:2127 generated CLIENT ALERT: Fatal - Handshake Failure
 - {bad_cert,hostname_check_failed}

=NOTICE REPORT==== 4-May-2024::08:25:08.978566 ===
TLS client: In state wait_cert_cr at ssl_handshake.erl:2127 generated CLIENT ALERT: Fatal - Handshake Failure
 - {bad_cert,hostname_check_failed}

this also results in a “fatal” handshake error

gun:open("stream.bybit.com", 443, #{trace => true, tls_opts => [{cacertfile, "/etc/ssl/cert.pem"}]}).

It probably depends on that the site is using wild card certs. So you need to configure for that.

{customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}

1> inets:start().
ok
2> ssl:start().
ok
3> httpc:request("https://stream.bybit.com:443").
{ok,{{"HTTP/1.1",404,"Not Found"},
     [{"connection","keep-alive"},
      {"date","Sat, 04 May 2024 09:41:56 GMT"},
      {"via",
       "1.1 d6095b4d9fa82f5d25465246e397ad4e.cloudfront.net (CloudFront)"},
      {"server","awselb/2.0"},
      {"content-length","14"},
      {"content-type","text/plain; charset=utf-8"},
      {"x-cache","Error from cloudfront"},
      {"x-amz-cf-pop","HEL51-P1"},
      {"x-amz-cf-id",
       "K2kvqv7SWuEvLpfUwYYk1HESv6zcWjS83dPfJi2vVijH_WV0sIXBpA=="}],
     "page not found"}}

That is default supported by httpc.

Hi,

Have a look at gunsmoke, a Hello-World example of using gun+websockets:

Note: something that tripped me up was that gun want’s to use HTTP2 as per default.

Cheers, Tobbe