Jq 失败并通过curl 在 SSE 端点上显示没有输出

问题描述 投票:0回答:2

Jq 的工作示例

echo 'data:{"id":"66fc29f995e5b148fe5c7f7d","summary":"Balans: 305.37","level":"info","date":"2024-10-01T16:57:29.873+00:00"}' | sed 's/data://g' | jq '.summary'

即使最后有新行

echo 'data:{"id":"66fc29f995e5b148fe5c7f7d","summary":"Balans: 305.37","level":"info","date":"2024-10-01T16:57:29.873+00:00"}
' | sed 's/data://g'  | jq '.summary'

输出(成功)

“巴兰斯:305.37”

无法使用 Curl(和 SSE 端点)的示例

curl -N --http2 -H "Accept:text/event-stream" --silent https://my_domain/stream/OyP1cEC3N7BTQrCsm3AHrTFAj5F5VKCH/notifications | sed 's/data://g' | jq '.summary'

这显示没有输出!我的问题是:为什么这不起作用? 然而,以下行确实显示了输出:

使用 Curl(和 SSE 端点)的工作示例,末尾没有 jq

anon@galliumos:~/Bureaublad$ curl -N --http2 -H "Accept:text/event-stream" --silent https://my_domain/stream/OyP1cEC3N7BTQrCsm3AHrTFAj5F5VKCH/notifications | sed 's/data://g'
{"id":"66fc310d95e5b148fe5c7f8d","summary":"Balans: 305.37","level":"info","date":"2024-10-01T17:27:41.679+00:00"}

我的 SSE 端点上的响应如下所示,并且正在运行:

data:{"id":"66fc310d95e5b148fe5c7f8d","summary":"Balans: 305.37","level":"info","date":"2024-10-01T17:27:41.679+00:00"}

data:{"id":"66fc310d95e5b148fe5c7f8a","summary":"Balans: 305.37","level":"info","date":"2024-10-01T17:27:41.679+00:00"}

... more records here ...

使用 NodeJS 更新本地 SSE 测试服务器

这提供了本地主机端口 3000 上的示例 SSE 端点。

  1. 创建一个名为
    server.js
    的文件并添加代码
  2. 运行服务器:
    node server.js
const http = require('http');
const port = process.env.PORT || 3000;

const server = http.createServer((req, res) => {
  // Server-sent events endpoint
  if (req.url === '/events') {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      ...(req.httpVersionMajor === 1 && { 'Connection': 'keep-alive' })
    });

    const refreshRate = 1000; // in milliseconds
    return setInterval(() => {
      const data = '{"id":"66fc310d95e5b148fe5c7f8d","summary":"Balans: 305.37","level":"info","date":"2024-10-01T17:27:41.679+00:00"}';
      const message = `data:${data}\n\n`;
      res.write(message);
    }, refreshRate);
  }

  // Client side
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end(`
    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title>SSE</title>
      </head>
      <body>
        <pre id="log"></pre>
      </body>
      <script>
        var eventSource = new EventSource('/events');
        eventSource.onmessage = function(event) {
          document.getElementById('log').innerHTML += event.data + '<br>';
        };
      </script>
    </html>
  `);
});

server.listen(port);

server.on('error', (err) => {
  console.log(err);
  process.exit(1);
});

server.on('listening', () => {
  console.log(`Listening on port ${port}`);
});

获取输出:

curl -N -H "Accept:text/event-stream" --silent http://localhost:3000/events

测试结果

我没有得到任何输出/结果:

curl -N -H "Accept:text/event-stream" --silent http://localhost:3000/events | jq -Rs 'match("data:(.*)")|.captures[0].string|fromjson|.summary'

curl -N -H "Accept:text/event-stream" --silent http://localhost:3000/events | tr -cd '[:print:]' | sed 's/^data://' | jq '.summary'
bash jq
2个回答
0
投票

尝试删除不可打印的字符

curl ... | tr -cd '[:print:]' | sed 's/^data://' | jq '.summary'

你应该得到

"Balans: 305.37"
"Balans: 305.37"
...

0
投票

完整的

jq
解决方案:

curl... | jq -Rs 'match("data:(.*)")|.captures[0].string|fromjson|.summary

详细:

  • jq --raw-input --slurp
    将输入作为原始字符串数据处理并捕获包括换行符在内的所有内容
  • match("data:(.*)")
    正则表达式匹配以
    data:
    开头的字符串并捕获
    .*
    此后正在进行的所有内容。
  • .captures[0].string
    这包含捕获的字符串,预计是原始 JSON。
  • fromjson| Parses the raw JSON into actual JSON data . 
    .summary` 从根对象输出摘要条目
© www.soinside.com 2019 - 2024. All rights reserved.