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.

1 Like

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.

1 Like

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