在 Orion 中通过 websockets 进行订阅

Subscriptions via websockets in Orion

是否可以从浏览器创建 websockets 订阅?我们正在使用分支 feature/1181_websockets 分支,git 版本 5ca6770aa401b52a31293fdcef4a9743fb1de2c4.

我们制作了一个 PoC,试图通过 websockets 订阅浏览器。我们尝试将浏览器中的一些 JS 代码 运行 连接到订阅 url。连接已建立,但 orion 在通过套接字从客户端发送数据时崩溃了。这个用例是否受支持?你有一个有效的例子吗? JS代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>

    <button id="send" type="button" name="button">send</button>

    <script type="text/javascript">
      var payload = `{"description": "One subscription to rule them all",
        "subject": {
          "entities": [{
            "idPattern": ".*",
            "type": "Room"
          }],
          "condition": {
            "attrs": ["temperature"],
            "expression": {
              "q": "temperature>40"
            }
          }
        },
        "expires": "2016-04-05T14:00:00.00Z",
        "throttling": 5
      }`;

      var ws = new WebSocket('ws://orion-url:9010/v2/subscriptions', 'ngsiv2-json');

      var button = document.getElementById('send');
      button.addEventListener('click', function(event) {
        ws.send(payload)
      });

    </script>


  </body>
</html>

作为替代方案,我们尝试使用 REST API 创建订阅,要求 Orion 通过 websockets 通知我们。我们发布了以下 JSON:

    {
    "description": "One subscription to rule them all",
    "subject": {
    "entities": [
      {
        "idPattern": ".*",
        "type": "Room"
      }
    ],
    "condition": {
      "attributes": [
        "temperature"
      ],
      "expression": {
        "q": "temperature>40"
      }
    }
    },
    "notification": {
      "callback": "ws://my-websocket-listener:8081"
    },
    "expires": "2016-04-05T14:00:00.00Z",
    "throttling": 5
    }

订阅过程失败,Orion returns 422 状态代码和消息:

    {
      "error": "BadRequest",
      "description": "Invalid URL"
    }

我们在订阅请求中是否有任何错误?这个用例是否受支持?

谢谢!

目前您可以使用浏览器订阅和接收通知,限制如下:

  1. 您可以从 WS 创建 WS 或 REST 订阅。
  2. 您无法从 REST 创建 WS 订阅。
  3. 只有在 REST 订阅中您可以指定回调,在 WS 中始终必须是 "ws://"。如果您创建 WS 订阅,创建者将成为接收者。
  4. 如果连接关闭,WS 订阅将被删除。

这里我以一小段代码为例,你只需要将URL改成你Orion的URL

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                window.WebSocket = window.WebSocket || window.MozWebSocket;
  // Here change with your URL
                var websocket = new WebSocket('ws://127.0.0.1:9010', 'ngsiv2-json');
                websocket.onopen = function () {
                    $('h1').css('color', 'green');
                };
                websocket.onerror = function () {
                    $('h1').css('color', 'red');
                };
                websocket.onmessage = function (message) {
                    console.log(message.data);
                    console.log(message);
                    $('div').append(message.data + '<br/>');
                };

                $('#send').click(function(e) {
                    e.preventDefault();
                    if ($('#txt').val().length > 0)
                    {
                        websocket.send($('#txt').val());
                        $('#txt').val('');
                    }
                });

                $('#new').click(function(e) {
                    e.preventDefault();
                    var msg = "{\"verb\":\"POST\",\"url\":\"/v2/entities\", \
                               \"params\":{\"options\":\"keyValues\"}, \
                               \"payload\":{\"type\":\"1\",\"id\":\"1\",\"temp\":1}}";

                    $('#txt').val(JSON.stringify(JSON.parse(msg), null, 2));
                });

                $('#upd').click(function(e) {
                    e.preventDefault();
                    var msg = "{\"verb\":\"POST\",\"url\":\"/v2/entities/1\", \
                                \"params\":{\"options\":\"keyValues\"},\"payload\":{\"temp\": 1}}";
                    $('#txt').val(JSON.stringify(JSON.parse(msg), null, 2));
                });

                $('#get').click(function(e) {
                    e.preventDefault();
                    var msg = "{\"verb\":\"GET\",\"url\":\"/v2/entities/1\"}";
                    $('#txt').val(JSON.stringify(JSON.parse(msg), null, 2));
                });

                $('#del').click(function(e) {
                    e.preventDefault();
                    var msg = "{\"verb\":\"DELETE\",\"url\":\"/v2/entities/1\"}";
                    $('#txt').val(JSON.stringify(JSON.parse(msg), null, 2));
                });

                $('#sub').click(function(e) {
                    e.preventDefault();
                    var msg = "{\"verb\":\"POST\",\"url\":\"/v2/subscriptions\", \
                                \"payload\":{\"description\":\"My subscription\", \
                                \"subject\":{\"entities\":[{\"id\":\"1\",\"type\":\"1\"}], \
                                \"condition\":{\"attributes\":[\"temp\"],\"expression\":{\"q\":\"temp>40\"}}}, \
                                \"notification\":{\"callback\":\"ws://\",\"attributes\":[\"temp\"], \
                                \"throttling\":5},\"expires\":\"2017-04-05T14:00:00.00Z\"}}";
                    $('#txt').val(JSON.stringify(JSON.parse(msg), null, 2));
                });
            });
        </script>
    </head>
    <body>
        <h1>WebSockets test</h1>
        <form>
            <table border="0">
            <tr>
                <td colspan="2">
                    <textarea rows="35" cols="70" id="txt"></textarea>
                </td>
            </tr>
            <tr>
                <td>
                    <button id="new">New</button>
                    <button id="upd">Update</button>
                    <button id="get">Show</button>
                    <button id="del">Delete</button>
                    <button id="sub">Subcription</button>
                </td>
                <td align="right">
                    <button id="send">Send</button>
                </td>
            </tr>
            </table>
        </form>
        <br/>
        <p>Server:</p>
        <div></div>
    </body>
</html>

我不是 JS 专家...但是当我在 WS for Orion 工作时,这对我来说是一种测试

干杯