Skip to content

Commit a74f763

Browse files
committed
specification: add RFC 7 (WebSocket transport)
1 parent 396a8f6 commit a74f763

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-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: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ 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 be exchanged over WebSockets, which is useful
24+
for interacting directly with browsers/JavaScript clients, see
25+
:ref:`websockets`.
26+
2327

2428
Transfer modes
2529
--------------
@@ -912,3 +916,75 @@ to be sent before it can continue as before.
912916

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

0 commit comments

Comments
 (0)