Squawk v2

Free Trial ➡

Squawk is realtime broadcast which includes important headlines, price movement and rumors as stories develop to give traders and investors news in the fastest and most convenient form.

Squawk is built on top of WebRTC. So one can connect to it through WebRTC supported browser using standard WebRTC API methods. Following are the methods that you will need to implement while writing a client for connecting to squawk.

Create a socket connection

First, create a web socket connection to squawk. The Benzinga Squawk service web socket address is:

wss://squawk-lb.benzinga.com/squawk

Authenticate

Once the socket connection is created, authenticate with your apikey.

{
    "apikey": "f5kec5x6gplwdv8o5dcn5aydtyx132u8",
    "name": "abc@xyz.com",
    "role": "viewer",
    "type": "auth",
    "id": "4158f900-d652-483a-8147-866d99ed9f8a"
}

Note: If you do not yet have an API key (apikey), please get in touch with the Benzinga licensing team. This is a one-time process. Save this API key securely.

The ID field (id) is a unique UUID string used to coordinate messages between client and server.

On successful authentication, you should get the following response:

{
    "iceServers": [{
        "urls": "turn:turnserver.benzinga.com:443",
        "username": "1567755301:XQbpzZ0YzltGon1q6paqbfensmE\u003d",
        "credential": "JfJBS295kI/5pjCQgGGJDgHv9ms\u003d"
    }],
    "id": "4158f900-d652-483a-8147-866d99ed9f8a"
}

Use this ice server details to initiate peer connections later with presenters/broadcasters to start listening to them.

Join Room

Once you have received the iceServers details authentication is done. Next send the join room request/message. The room name for benzinga broadcasts is PRO. Sample join room request format:

{
    "room": "PRO",
    "type": "joinRoom",
    "id": "a5fd1a15-17cf-4f66-83a2-0d77704e1870"
}

In join room response, you should get the list of existing presenters (broadcaster) in the following format:

{
    "existingPresenters": [{
        "userId": "6s7c6:b:53l54g85-bc4d-4pb4-7s3c-e95519546007",
        "username": "Charles Gross"
    }],
    "id": "a5fd1a15-17cf-4f66-83a2-0d77704e1870"
}

Create peer connections

Add the existingPresenters received in joinRoom response as participants and create a peer connection with each of the presenters to start listening to them. Please note that this peer connection type should be receiveOnly, meaning you will be able to only receive the audio stream, and not send anything. The iceServer details received after authentication will be used to create peer connections later. Sample SDP offer for peer connection will look like as below:

{
    "sdpOffer": "v=0\r\no=- 2217917876931547465 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=msid-semantic: WMS\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:40GQ\r\na=ice-pwd:6fK0yHKYhailmhIoyClkgcTe\r\na=ice-options:trickle\r\na=fingerprint:sha-256 D2:A1:87:77:B1:42:56:84:6A:C7:74:1D:91:E2:BD:E0:21:10:AF:E3:61:2D:E2:71:B1:5D:D0:09:F3:19:8E:CF\r\na=setup:actpass\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:3 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:5 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=recvonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:104 ISAC/32000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:110 telephone-event/48000\r\na=rtpmap:112 telephone-event/32000\r\na=rtpmap:113 telephone-event/16000\r\na=rtpmap:126 telephone-event/8000\r\n",
    "userId": "6s7c6:b:53l54g85-bc4d-4pb4-7s3c-e95519546007",
    "type": "receiveMedia",
    "id": "07ad868c-3946-4e8d-a81f-c67ad249f9ef"
}

Notice that the userId is the same as you receive in presenters list after joining the room. And in response you should get following SDP Answer with the same id:

{
    "sdpAnswer": "v\u003d0\r\no\u003d- 3776677610 3776677610 IN IP4 0.0.0.0\r\ns\u003dKurento Media Server\r\nc\u003dIN IP4 0.0.0.0\r\nt\u003d0 0\r\na\u003dmsid-semantic: WMS\r\na\u003dgroup:BUNDLE 0\r\nm\u003daudio 1 UDP/TLS/RTP/SAVPF 111 0\r\na\u003dsendonly\r\na\u003dmid:0\r\na\u003drtcp:9 IN IP4 0.0.0.0\r\na\u003drtpmap:111 opus/48000/2\r\na\u003drtpmap:0 PCMU/8000\r\na\u003dsetup:active\r\na\u003drtcp-mux\r\na\u003dfmtp:111 minptime\u003d10;useinbandfec\u003d1\r\na\u003dssrc:3259874899 cname:user3003646761@host-f035f63\r\na\u003dice-ufrag:ZEqH\r\na\u003dice-pwd:c9hVTWeSptMEFmUB8BTUnY\r\na\u003dfingerprint:sha-256 BF:AE:4D:4B:72:78:40:0F:72:E7:B3:41:31:DB:1D:D6:A6:F6:45:DB:31:36:03:49:30:0C:70:7A:7D:85:86:6A\r\n",
    "id": "07ad868c-3946-4e8d-a81f-c67ad249f9ef"
}

If you receive any error then, reject the connection.

Send Ice Candidate to peers

Typical request/message format to send iceCandidate:

{
    "candidate": {
        "candidate": "candidate:2315357691 1 udp 2113937151 192.168.2.5 49040 typ host generation 0 ufrag IRp1 network-cost 999",
        "sdpMid": "0",
        "sdpMLineIndex": 0
    },
    "userId": "5e098:b:53d53f95-ad4d-4eb4-9b4c-c84519546030",
    "type": "iceCandidate",
    "id": "50438f33-f2b5-47aa-a0b2-0cb2a082af96"
}

Message Types

You should add a handler for the following message types

  1. newPresenterArrived Indicating the new presenter/broadcaster has joined. Add new presenter creating a new peer connection. typical newPresenterArrived message will be as follow:
       {
         "user": {
           "userId": "6s7c6:b:53l54g85-bc4d-4pb4-7s3c-e95519546007",
           "username": "Charles Gross"
         },
         "type": "newPresenterArrived"
       }
    
  2. iceCandidate Add the iceCandidate to the participant. A typical iceCandidate message/request will be in following format:
       {
         "userId": "6s7c6:b:53l54g85-bc4d-4pb4-7s3c-e95519546007",
         "candidate": {
           "candidate": "candidate:5 2 TCP 1015022078 10.0.2.227 9 typ host tcptype active",
           "sdpMid": "0",
           "sdpMLineIndex": 0
         },
         "type": "iceCandidate"
       }
    
    From userId, you can map the iceCandidate to the existing presenter/participant.
  3. presenterLeft Close the peer connection and remove the presenter using received userId in the message. Typical presenterLeft message will be received in below format:

       {
         "userId": "6s7c6:b:53l54g85-bc4d-4pb4-7s3c-e95519546007",
         "type": "presenterLeft"
       }
    
  4. mediaOverride Meaning this use has started playing from another session (could be logged in from another browser/client). So discard all peer connection and disconnect from this session. The mediaOverride message will be in the following format:

       {
         "type": "mediaOverride"
       }
    

Ping/Pong mechanism to keep alive the Web Socket

Implement the regular interval ping messages to keep the Web Socket connection alive. Every 25-30 seconds should be good enough. Ping request format:

{
    "type": "ping",
    "id": "e4809b6b-319a-4fa9-94e0-94ae86a33f13"
}

In response, you should just get same id:

{
    "id": "e4809b6b-319a-4fa9-94e0-94ae86a33f13"
}

Logout

Send the logout message when you want to stop listening or your container application's session ends. The logout request/message should be:

{
    "type": "logout",
    "id": "9461455c-6f4b-438d-b182-72cc2304521d"
}

Note that the value of id (here UUID) is unique with each message chain.