Connect by JBRH Open Connect

SIP over WebSocket

A browser cannot open the raw sockets ordinary SIP uses, so SIP is carried inside a WebSocket with the sip subprotocol. The browser registers with a registrar over that connection, receives and places calls through it, and hands the audio to WebRTC. Connect's softphone works this way: a person's own line is a channel_routes row with channel='softphone'.

Status
Reference What this means
Audience
developer, both
Channels
phone
In the app
#/calls, #/phone-advanced
Last verified
Product version
6.3.2

Registration, and what keeps it#

Registration is the browser telling a registrar *this account is reachable at this connection*. It is not permanent. Every registration carries an expiry, and the client must renew before it lapses; a laptop that slept through the renewal is not registered when it wakes, regardless of what the screen still says.

  1. Open the WebSocket, negotiating the sip subprotocol.

    Result Both ends agree the frames are SIP. A mismatch here opens a connection that never carries anything, which reads as a hang.

  2. Send a REGISTER; answer the authentication challenge that comes back.

    Result The registrar knows which account this connection belongs to.

  3. Re-register before the expiry, every time.

    Result Inbound calls keep finding you. Miss it and calls route to whatever the account's fallback is — often voicemail, sometimes nothing.

  4. Accept an inbound INVITE, or send one, and negotiate media.

    Result Signalling is settled on this connection; audio flows over the separate WebRTC path.

Because the address a browser can advertise is not reachable from outside, an inbound call has to come back down the connection that is already open. This is why a softphone works behind a network that would refuse to accept an incoming connection — and why a proxy that mishandles that return path produces a line that registers cleanly and never rings.

The addressing mistakes that cost days#

Every one of these fails without an error message, which is what makes them expensive. The connection looks fine; the calls do not happen.

MistakeWhat you seeThe correction
Using the service's web hostname as the SIP hostThe socket opens or times out; registration never completesA hosted platform's SIP host is frequently a different name from the one in its web or API URL. Read it from the platform's SIP settings, never infer it
Writing sip:host:port where a bare host:port is expectedThe field is accepted and saved; nothing routesMatch the field's expected form exactly. A scheme prefix in a field that does not want one is not normalised away
Assuming a number is linked to a trunk because both existOutbound works; inbound never arrivesThe association between a number and a trunk is its own step, and on some platforms it exists only in a console rather than in an API
Testing inbound by calling from the same platformA call that appears to work and proves nothingOriginate the test from the outside, over the real path a customer would use

Does Connect use SIP over WebSocket?#

Used, for the browser softphone. It is the signalling transport for a person's own line, and it is the only place in the product where a WebSocket carries anything — the application's own event stream is server-sent events.

It is not how the engine's own calls are carried. Connect runs two phone engines: a turn-based carrier path and a realtime speech-to-speech path a workspace opts into, with the PSTN leg handled by a carrier and, on the realtime engine, LiveKit SIP in front of the model. A softphone is a person's handset; those are the business's lines.

Reading a softphone fault#

The line will not register
Signalling. Check the SIP host, the credentials and whether the socket is reaching the registrar at all.
Registers, then drops after a few minutes
The renewal is not happening, or an intermediary is closing an idle connection. Both look identical from the screen.
Registers, outbound works, inbound never rings
Almost never the browser. The number is not routed to the trunk, or the return path through the proxy is broken.
Connects and is silent
Not signalling at all — that is the media path, and it has its own causes. Voice line health escalates operational problems into Needs You, where they drain by themselves as the cause clears.

Questions#

Why does the softphone need a WebSocket when the rest of the app does not?

Because SIP is a two-way conversation with its own message flow, and a browser has no other way to carry it. Product notifications only travel one way, which is why they use an event stream instead. Two different problems, two different transports.

Can I use a desk phone instead of the browser?

That is a carrier and account question rather than a Connect one — a line that registers over ordinary SIP is between the device and the provider. What Connect models is the route: channel_routes with channel='softphone' is specifically the browser line.

Is the signalling connection encrypted?

It runs over a secure WebSocket, so the signalling is protected in transit. The media is encrypted separately and unconditionally by WebRTC. Neither fact tells you anything about the PSTN leg beyond the carrier, which is outside both.