WebSockets: Connect and Interact in terminal
Published: 2024-01-11 04:19:23

## Additional Resources:

- WebSocket RFC: [https://www.rfc-editor.org/rfc/rfc6455.html](https://www.rfc-editor.org/rfc/rfc6455.html)
- cURL documentation: [https://curl.se/docs/manpage.html](https://curl.se/docs/manpage.html)

WebSockets provide a way to establish two-way, real-time communication between client and a server. Compared to traditional HTTP requests, WebSockets offer continuous data exchange without the need for repeated connections, which means through a single TCP/IP socket connection. This makes them ideal for applications like live chat, streaming platforms, and real-time games.

![WebSocket protocol illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf0we3cseadc6ofoucep.png)

However, <u>not all tools directly support WebSockets out of the box</u>. This guide will show you how to leverage cURL and explore alternative options to establish and interact with WebSocket connections.

## **Using cURL**

While cURL doesn't natively support WebSockets, you can mimic the handshake process by manually specifying websocket specific headers and flags.

```Bash
# Indicates a persistent connection with upgrade to WebSocket protocol
Connection: keep-alive, upgrade
Upgrade: websocket
# Random base64 encoded key
Sec-WebSocket-Key: <your_websocket_key>
Sec-WebSocket-Version: 13
```

> 💡 For cUrl not to terminate its process when there’s no stdout you should use `--no-buffer` or `-N` flag (for short).
> From [cUrl docs:](https://curl.se/docs/manpage.html#-N)
> _In normal work situations, curl uses a standard buffered output stream that has the effect that it outputs the data in chunks, not necessarily exactly when the data arrives. Using this option disables that buffering._
> 

The following command connects to 

`wss://ws.garantex.org/?stream=global&stream=btcrub&stream=ext_markets&stream=order&stream=trade&stream=member_balance&stream=exchanger`

and subscribes to various scenarios, defined on the server.

Notice how it specifically uses http1.1, because http2 works in a different way.

```bash
curl \
--no-buffer \
-sSv \
--http1.1 \
--header "Connection: keep-alive, upgrade" \
--header "Upgrade: websocket" \
--header "Sec-WebSocket-Key: N509hQQwSFGfanhbxP3F6g==" \
--header "Sec-WebSocket-Version: 13" \
--url-query "stream=global" \
--url-query "stream=btcrub" \
--url-query "stream=ext_markets" \
--url-query "stream=order" \
--url-query "stream=trade" \
--url-query "stream=member_balance" \
--url-query "stream=exchanger" \
https://ws.garantex.org/
```
Note:
`-s or —silent` to suppress progress meter
`-S or —show-error` in addition to -s disables progress meter but still show error messages
`-v or --verbose` to show request and response headers
You may use just a single query sting `--url-query "stream=global&stream=btcrub&stream=ext_markets&stream=order&stream=trade&stream=member_balance&stream=exchanger”`

## **Beyond cURL: Alternative WebSocket Clients**

There are not many (that i could find)

- cUrl kind of supports it, but i have not tested if you can communicate to server via stdin
- [httpie](https://httpie.io/docs/cli/examples) sadly does <u>not</u> support websocket protocol (both cli and gui app)
- postman does support websockets, but it’s paid software now
- [insomnia](https://insomnia.rest/) is pretty good (but personally i like httpie more) and does support websockets (free for personal use)

### There are dedicated cli utilities to working with websockets:

[wscat](https://github.com/websockets/wscat) is nodejs based (so you will actually need to set up node environment)

```bash
wscat -c "wss://ws.garantex.org/?stream=global"
```

[websocat](https://github.com/vi/websocat) native command-line tool, but i found it a bit overly complicated for my sort of task

```bash
websocat "wss://ws.garantex.org/?stream=global"
```

### Others to explore

- [wstunnel](https://github.com/erebe/wstunnel)
- [websocketd](https://github.com/joewalnes/websocketd)
- [wsd](https://github.com/alexanderGugel/wsd)

## Browser (any modern browser)

In ECMAScript 6 (ES6) [WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) was added to javascript, so you may simply open devtools console and type in:

```jsx
// creates connection
const ws = new WebSocket('wss://ws.garantex.org/?stream=global');

// returns current state of the connection
ws.readyState

// prints out response messages
ws.onmessage = function (e) { console.log(e.data) };

// communicate with the server
ws.send('Hello world!');

// self explanatory
ws.close();
```