Skip to content

Commit f7fe97a

Browse files
committed
specification: add RFC 7 (WebSocket transport)
1 parent 68b2703 commit f7fe97a

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

protocol/specification/discovery.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,4 @@ Implementation hints
7979
See also `SECoP RFC 5`_.
8080

8181

82-
.. _SECoP RFC 6: https://github.com/SampleEnvironment/SECoP/blob/master/rfcs/RFC-005-udp-discovery.rst
82+
.. _SECoP RFC 5: https://github.com/SampleEnvironment/SECoP/blob/master/rfcs/RFC-005-udp-discovery.rst

protocol/specification/messages.rst

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ needed. This should offer multiple TCP connections and contain the necessary
2020
logic to map requests/replies from/to those network connections onto/from the
2121
serial connection to the actual SEC node.
2222

23+
Finally, SECoP messages can also exchanged over WebSockets, which is useful for
24+
interacting directly with browsers/JavaScript clients, see :ref:`websockets`.
25+
2326

2427
Transfer modes
2528
--------------
@@ -912,3 +915,75 @@ to be sent before it can continue as before.
912915

913916
| :issue:`004 The Timeout SEC Node Property`
914917
| :issue:`006 Keep Alive`
918+
919+
920+
.. _websockets:
921+
922+
SECoP over WebSockets
923+
---------------------
924+
925+
Since browser (i.e. HTML+JavaScript) based human interface solutions are more
926+
and more important, and JavaScript lacks traditional socket based APIs,
927+
exchanging raw SECoP messages is not an option. The best alternative is
928+
WebSockets (RFC :rfc:`6455`), which are a relatively overhead-free way of
929+
exchanging messages between two endpoints in an arbitrary pattern.
930+
931+
See also `SECoP RFC 7`_.
932+
933+
Implementation in a SEC node
934+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
935+
936+
After opening a connection, if the first message the SEC node receives starts
937+
with ``GET /``, it treats the connection as a WebSocket connection, i.e. it
938+
negotiates the connection using a prelude of HTTP requests, after which the
939+
connection continues using the WebSocket protocol in both directions.
940+
941+
Since WebSockets provide reliable framing, every SECoP message is sent in a
942+
frame. The line ending added to separate messages over raw TCP is therefore
943+
unneded, but remains valid. Messages are sent as TEXT frames.
944+
945+
Everything else (message structure and semantics) remains unchanged.
946+
947+
.. note::
948+
949+
If the SEC node doesn't want to support WebSockets, no further action is
950+
required. It will reply with the standard SECoP error messages, and the
951+
client will abort the connection attempt.
952+
953+
A minimal implementation of the HTTP prelude is pretty small, does not have
954+
a lot of complexity, and can be implemented even on microcontrollers `in
955+
about 200 lines of code
956+
<https://github.com/SampleEnvironment/microSECoP/blob/master/src/http.rs>`_.
957+
958+
Implementation in a client
959+
~~~~~~~~~~~~~~~~~~~~~~~~~~
960+
961+
On the WebSocket client side, making a connection is as easy as opening a
962+
connection and start sending request messages, handling response messages as
963+
they come in. A very minimal example in JavaScript::
964+
965+
function on_connect(event) {
966+
// On initial connect, we should ask for identification
967+
event.target.send('*IDN?');
968+
}
969+
970+
function on_message(event) {
971+
let msg = event.data;
972+
// Handle response to initial *IDN? and request descriptive data
973+
if (msg.startsWith('ISSE')) {
974+
event.target.send('describe');
975+
return;
976+
}
977+
// Parse `msg` as a SECoP message here, and react to it
978+
}
979+
980+
let ws = new WebSocket('ws://node:10767');
981+
ws.addEventListener('open', on_connect);
982+
ws.addEventListener('message', on_message);
983+
// Should also listen on 'close' and 'error' events
984+
985+
// Whenever needed, send messages, for example:
986+
ws.send('change mod:param 42');
987+
988+
989+
.. _SECoP RFC 7: https://github.com/SampleEnvironment/SECoP/blob/master/rfcs/RFC-007-websockets.rst

0 commit comments

Comments
 (0)