KirillBelov/ WebSocketLink

Web socket connection client

Contributed by: Kirill Belov

This package allows you to connect to remote servers that operate using the WS or WSS protocol. Once connected, you can send messages to the remote server and receive messages.

Installation Instructions

To install this paclet in your Wolfram Language environment, evaluate this code:
PacletInstall["KirillBelov/WebSocketLink"]

Examples

Basic Examples (7) 

Import the package:

In[1]:=
<< KirillBelov`WebSocketLink`
In[2]:=
WebSocketConnectionObject[]
Out[2]=

Let's create a connection:

In[3]:=
connection = WebSocketConnect[
  "wss://stream.binance.com:9443/ws/btcusdt@miniTicker"]

Let's see what came after a few seconds:

In[4]:=
connection["Data"]
Out[4]=

You can retrieve the latest received data:

In[5]:=
ImportString[connection["Data"]["Part", -1], "RawJSON"]
Out[5]=

Let's send a message and subscribe to another stream:

In[6]:=
frame = ExportString[<|"method" -> "SUBSCRIBE", "params" -> {"btcusdt@depth"}, "id" -> 1|>, "RawJSON"]
Out[6]=
In[7]:=
WebSocketSend[connection, frame]
Out[7]=

After that we will be able to receive data of another type:

In[8]:=
Short@
 SelectFirst[#e == "depthUpdate" &]@
  Select[KeyExistsQ[#, "e"] &]@
   Map[ImportString[#, "RawJSON"] &] @ connection["Data"]["Elements"]
Out[8]=

Let's close the connection:

In[9]:=
WebSocketClose[connection]
Out[9]=

Scope (15) 

Custom serializer (5) 

By default you can send to the server frames as a string, but you can use custom serialiser for frames:

In[10]:=
connection = WebSocketConnect[
  "wss://stream.binance.com:9443/ws/btcusdt@miniTicker"]
Out[10]=
In[11]:=
miniTickerSerialize[pair_String] := ExportString[<|"method" -> "SUBSCRIBE", "params" -> {pair <> "@miniTicker"}, "id" -> RandomInteger[{1, 1000}]|>, "RawJSON"]

Use this serializer:

In[12]:=
WebSocketSend[connection, "ethusdt", "Serializer" -> miniTickerSerialize]
Out[12]=

Extract data for ETHUSDT:

In[13]:=
Short[ethusdtTicker =
  Query[All, {"E"/*(#/1000 &)/*FromUnixTime, "c"/*ToExpression}]@
   Select[KeyExistsQ[#, "s"] && #[["s"]] == "ETHUSDT" &]@
    Map[ImportString[#, "RawJSON"] &]@
     connection["Data"]["Elements"]]
Out[13]=

And plot the price of the coin:

In[14]:=
DateListPlot[ethusdtTicker, PlotTheme -> "Marketing", FrameLabel -> {"time", "ETH price in USDT"}]
Out[14]=

Close the connection:

In[15]:=
WebSocketClose[connection]
Out[15]=

Custom deserializer (4) 

Also you can use custom deserializer:

In[16]:=
miniTickerDeserialize[miniTicker_String] :=
 Query[<|"Time" -> "E"/*(#/1000 &)/*FromUnixTime, "Price" -> "c"/*ToExpression|>]@
  ImportString[miniTicker, "RawJSON"]
In[17]:=
connection = WebSocketConnect[
  "wss://stream.binance.com:9443/ws/btcusdt@miniTicker", "Deserializer" -> miniTickerDeserialize
  ]
Out[17]=

Now the saved data is immediately in the form of an expression and not a string:

In[18]:=
btcusdtMiniTicker = Values@connection["Data"]["Elements"];

Plot it:

In[19]:=
DateListPlot[btcusdtMiniTicker, PlotTheme -> "Marketing", FrameLabel -> {"time", "BTC price in USDT"}]
Out[19]=

Close connection:

In[20]:=
WebSocketClose[connection]
Out[20]=

Event handler (6) 

You can add custom event handler that will be process all received messages

First define a deserializer:

In[21]:=
klineDeserialize[message_String] := Module[{k = ImportString[message, "RawJSON"]}, <|
   "s" -> k["s"], "t" -> FromUnixTime[k["k", "t"]/1000], "o" -> ToExpression[k["k", "o"]], "h" -> ToExpression[k["k", "h"]], "l" -> ToExpression[k["k", "l"]], "c" -> ToExpression[k["k", "c"]], "v" -> ToExpression[k["k", "v"]]
   |>
  ]

Let's create a separate variable to store the results of processing:

In[22]:=
klines = <||>;

And the handler itself, which will not save unnecessary data on candles. After all, candles are completed once in a certain period, and the last candle is updated every few seconds:

In[23]:=
klineEventHandler[connection_, kline_] := (
  Print[kline];
  If[! KeyExistsQ[klines, kline["s"]], klines[kline["s"]] = <||>]; klines[kline["s"], kline["t"] ] = {kline["t"], Values[kline[[{"o", "h", "l", "c", "v"}]]]}
  )

Create a connection:

In[24]:=
connection = WebSocketConnect["wss://stream.binance.com:9443/ws/btcusdt@kline_3m", "Deserializer" -> klineDeserialize, "EventHandler" -> klineEventHandler
  ]
Out[24]=

After several minutes you can plot the graphic with BTCUSDT candlestick:

In[25]:=
TradingChart[Values@klines[["BTCUSDT", All]], PlotTheme -> "Detailed"]
Out[25]=

Close connection:

In[26]:=
WebSocketClose[connection]
Out[26]=

Publisher

Kirill Belov

Disclosures

Compatibility

Wolfram Language Version 13

Version History

  • 1.0.2 – 20 March 2024
  • 1.0.1 – 14 January 2023
  • 1.0.0 – 13 January 2023

License Information

MIT License

Paclet Source

Source Metadata

See Also