<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Stream on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/</link><description>Recent content in Stream on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/index.xml" rel="self" type="application/rss+xml"/><item><title>Stream.on()</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-on/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-on/</guid><content><![CDATA[&lt;h1 id=&#34;streamon&#34;&gt;Stream.on()&lt;/h1&gt;
&lt;p&gt;Set up handler functions for various events on the gRPC stream.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Parameter&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;event&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;The event name to define a handler for.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;handler&lt;/td&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/event-handler/&#34;&gt;&lt;code&gt;EventHandler&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;The function to call when the event happens.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;p&gt;Possible events:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Event name&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;data&lt;/td&gt;
              &lt;td&gt;Emitted when the server sends data.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;error&lt;/td&gt;
              &lt;td&gt;Emitted when an error occurs. In case of the error, an 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-error/&#34;&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/a&gt; object sends to the handler function.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;end&lt;/td&gt;
              &lt;td&gt;Emitted when the server closes the incoming stream.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;

&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;When you enable the experimental 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/feature-flags/&#34;&gt;&lt;code&gt;async-metric-context&lt;/code&gt; feature flag&lt;/a&gt;, each &lt;code&gt;Stream.on()&lt;/code&gt; handler captures the tags and metadata active when you register it. Metrics emitted by the handler use a copy of that context, and k6 restores the interrupted context after the handler returns or throws. Promise reactions and &lt;code&gt;await&lt;/code&gt; continuations created by the handler keep its context.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;div class=&#34;code-group&#34; data-props=&#39;{&#34;labels&#34;: [&#34;Simple example&#34;], &#34;lineNumbers&#34;: [true]}&#39;&gt;
&lt;!-- md-k6:skip --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);

export default () =&amp;gt; {
  if (__ITER == 0) {
    client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
  }

  const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);

  // sets up a handler for the data (server sends data) event
  stream.on(&amp;#39;data&amp;#39;, (stats) =&amp;gt; {
    console.log(&amp;#39;Finished trip with&amp;#39;, stats.pointCount, &amp;#39;points&amp;#39;);
    console.log(&amp;#39;Passed&amp;#39;, stats.featureCount, &amp;#39;features&amp;#39;);
    console.log(&amp;#39;Traveled&amp;#39;, stats.distance, &amp;#39;meters&amp;#39;);
    console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
  });

  // sets up a handler for the end event (stream closes)
  stream.on(&amp;#39;end&amp;#39;, function () {
    // The server has finished sending
    client.close();
    console.log(&amp;#39;All done&amp;#39;);
  });

  // sets up a handler for the error event (an error occurs)
  stream.on(&amp;#39;error&amp;#39;, function (e) {
    // An error has occurred and the stream has been closed.
    console.log(&amp;#39;Error: &amp;#39; &amp;#43; JSON.stringify(e));
  });

  sleep(1);
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="streamon">Stream.on()&lt;/h1>
&lt;p>Set up handler functions for various events on the gRPC stream.&lt;/p>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>event&lt;/td>
&lt;td>string&lt;/td>
&lt;td>The event name to define a handler for.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>handler&lt;/td>
&lt;td>
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/event-handler/">&lt;code>EventHandler&lt;/code>&lt;/a>&lt;/td>
&lt;td>The function to call when the event happens.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section>&lt;p>Possible events:&lt;/p></description></item><item><title>Error</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-error/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-error/</guid><content><![CDATA[&lt;h1 id=&#34;error&#34;&gt;Error&lt;/h1&gt;
&lt;p&gt;The error object is the object that is passed to the &lt;code&gt;error&lt;/code&gt; event handler function.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;Error.code&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;number&lt;/td&gt;
              &lt;td&gt;A gRPC error code.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;Error.details&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;array&lt;/td&gt;
              &lt;td&gt;A list of details attached to the error.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;Error.message&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;An original error message.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;]]></content><description>&lt;h1 id="error">Error&lt;/h1>
&lt;p>The error object is the object that is passed to the &lt;code>error&lt;/code> event handler function.&lt;/p>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>Error.code&lt;/code>&lt;/td>
&lt;td>number&lt;/td>
&lt;td>A gRPC error code.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Error.details&lt;/code>&lt;/td>
&lt;td>array&lt;/td>
&lt;td>A list of details attached to the error.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Error.message&lt;/code>&lt;/td>
&lt;td>string&lt;/td>
&lt;td>An original error message.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section></description></item><item><title>Stream.end()</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-end/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-end/</guid><content><![CDATA[&lt;h1 id=&#34;streamend&#34;&gt;Stream.end()&lt;/h1&gt;
&lt;p&gt;Signals to the server that the client has finished sending messages.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;div class=&#34;code-group&#34; data-props=&#39;{&#34;labels&#34;: [&#34;Simple example&#34;], &#34;lineNumbers&#34;: [true]}&#39;&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);

export default () =&amp;gt; {
  if (__ITER == 0) {
    client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
  }

  const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);

  stream.on(&amp;#39;data&amp;#39;, (stats) =&amp;gt; {
    console.log(&amp;#39;Finished trip with&amp;#39;, stats.pointCount, &amp;#39;points&amp;#39;);
    console.log(&amp;#39;Passed&amp;#39;, stats.featureCount, &amp;#39;features&amp;#39;);
    console.log(&amp;#39;Traveled&amp;#39;, stats.distance, &amp;#39;meters&amp;#39;);
    console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
  });

  // send 2 items
  stream.write({ latitude: 406109563, longitude: -742186778 });
  stream.write({ latitude: 416802456, longitude: -742370183 });

  // send end-signal to the server
  stream.end();

  sleep(1);
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="streamend">Stream.end()&lt;/h1>
&lt;p>Signals to the server that the client has finished sending messages.&lt;/p>
&lt;h3 id="example">Example&lt;/h3>
&lt;div class="code-group" data-props='{"labels": ["Simple example"], "lineNumbers": [true]}'>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;
const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);
export default () =&amp;gt; {
if (__ITER == 0) {
client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
}
const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);
stream.on(&amp;#39;data&amp;#39;, (stats) =&amp;gt; {
console.log(&amp;#39;Finished trip with&amp;#39;, stats.pointCount, &amp;#39;points&amp;#39;);
console.log(&amp;#39;Passed&amp;#39;, stats.featureCount, &amp;#39;features&amp;#39;);
console.log(&amp;#39;Traveled&amp;#39;, stats.distance, &amp;#39;meters&amp;#39;);
console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
});
// send 2 items
stream.write({ latitude: 406109563, longitude: -742186778 });
stream.write({ latitude: 416802456, longitude: -742370183 });
// send end-signal to the server
stream.end();
sleep(1);
};&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;/div></description></item><item><title>Stream.write()</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-write/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-write/</guid><content><![CDATA[&lt;h1 id=&#34;streamwrite&#34;&gt;Stream.write()&lt;/h1&gt;
&lt;p&gt;Writes a message to the stream. The message is a canonical request object, as-per the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/protocols/grpc/#protocol-buffers-json-mapping&#34;&gt;Protobuf JSON Mapping&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;div class=&#34;code-group&#34; data-props=&#39;{&#34;labels&#34;: [&#34;Simple example&#34;], &#34;lineNumbers&#34;: [true]}&#39;&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);

export default () =&amp;gt; {
  if (__ITER == 0) {
    client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
  }

  const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);

  stream.on(&amp;#39;data&amp;#39;, (stats) =&amp;gt; {
    console.log(&amp;#39;Finished trip with&amp;#39;, stats.pointCount, &amp;#39;points&amp;#39;);
  });

  // send an item
  stream.write({ latitude: 406109563, longitude: -742186778 });

  // send end-signal to the server
  stream.end();

  sleep(1);
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="streamwrite">Stream.write()&lt;/h1>
&lt;p>Writes a message to the stream. The message is a canonical request object, as-per the
&lt;a href="/docs/k6/v2.3.x/using-k6/protocols/grpc/#protocol-buffers-json-mapping">Protobuf JSON Mapping&lt;/a>.&lt;/p>
&lt;h3 id="example">Example&lt;/h3>
&lt;div class="code-group" data-props='{"labels": ["Simple example"], "lineNumbers": [true]}'>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;
const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);
export default () =&amp;gt; {
if (__ITER == 0) {
client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
}
const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);
stream.on(&amp;#39;data&amp;#39;, (stats) =&amp;gt; {
console.log(&amp;#39;Finished trip with&amp;#39;, stats.pointCount, &amp;#39;points&amp;#39;);
});
// send an item
stream.write({ latitude: 406109563, longitude: -742186778 });
// send end-signal to the server
stream.end();
sleep(1);
};&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;/div></description></item><item><title>Event Handler</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/event-handler/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/event-handler/</guid><content><![CDATA[&lt;h1 id=&#34;event-handler&#34;&gt;Event Handler&lt;/h1&gt;
&lt;p&gt;The function to call for various events on the gRPC stream. It is set up using the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-on/&#34;&gt;&lt;code&gt;stream.on()&lt;/code&gt;&lt;/a&gt; method.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;data&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;object or 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-error/&#34;&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;It&amp;rsquo;s either object with the data from server (a message) or an error object, in case of &lt;code&gt;error&lt;/code&gt; event&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;metadata&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/message-metadata/&#34;&gt;&lt;code&gt;Metadata&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;The object that represents the gRPC stream&amp;rsquo;s message metadata.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;div class=&#34;code-group&#34; data-props=&#39;{&#34;labels&#34;: [&#34;A handler metadata example&#34;], &#34;lineNumbers&#34;: [true]}&#39;&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);

export default () =&amp;gt; {
  if (__ITER == 0) {
    client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
  }

  const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);

  // sets up a handler for the data (server sends data) event
  stream.on(&amp;#39;data&amp;#39;, (stats, metadata) =&amp;gt; {
    console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
    console.log(&amp;#39;This message has been received:&amp;#39;, metadata.ts);
  });

  stream.on(&amp;#39;end&amp;#39;, function () {
    // The server has finished sending
    client.close();
  });

  sleep(1);
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="event-handler">Event Handler&lt;/h1>
&lt;p>The function to call for various events on the gRPC stream. It is set up using the
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-on/">&lt;code>stream.on()&lt;/code>&lt;/a> method.&lt;/p>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>data&lt;/code>&lt;/td>
&lt;td>object or
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/stream-error/">&lt;code>Error&lt;/code>&lt;/a>&lt;/td>
&lt;td>It&amp;rsquo;s either object with the data from server (a message) or an error object, in case of &lt;code>error&lt;/code> event&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>metadata&lt;/code>&lt;/td>
&lt;td>
&lt;a href="/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/message-metadata/">&lt;code>Metadata&lt;/code>&lt;/a>&lt;/td>
&lt;td>The object that represents the gRPC stream&amp;rsquo;s message metadata.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section>&lt;h3 id="example">Example&lt;/h3>
&lt;div class="code-group" data-props='{"labels": ["A handler metadata example"], "lineNumbers": [true]}'>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;
const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);
export default () =&amp;gt; {
if (__ITER == 0) {
client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
}
const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);
// sets up a handler for the data (server sends data) event
stream.on(&amp;#39;data&amp;#39;, (stats, metadata) =&amp;gt; {
console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
console.log(&amp;#39;This message has been received:&amp;#39;, metadata.ts);
});
stream.on(&amp;#39;end&amp;#39;, function () {
// The server has finished sending
client.close();
});
sleep(1);
};&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;/div></description></item><item><title>Metadata</title><link>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/message-metadata/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/javascript-api/k6-net-grpc/stream/message-metadata/</guid><content><![CDATA[&lt;h1 id=&#34;metadata&#34;&gt;Metadata&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;Metadata&lt;/code&gt; is an object that represents the gRPC stream&amp;rsquo;s message.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;Metadata.ts&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;number&lt;/td&gt;
              &lt;td&gt;Contains the timestamp of the original event. For example, when a message has been received.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;div class=&#34;code-group&#34; data-props=&#39;{&#34;labels&#34;: [&#34;A handler metadata example&#34;], &#34;lineNumbers&#34;: [true]}&#39;&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);

export default () =&amp;gt; {
  if (__ITER == 0) {
    client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
  }

  const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);

  // sets up a handler for the data (server sends data) event
  stream.on(&amp;#39;data&amp;#39;, (stats, metadata) =&amp;gt; {
    console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
    console.log(&amp;#39;This message has been received:&amp;#39;, metadata.ts);
  });

  stream.on(&amp;#39;end&amp;#39;, function () {
    // The server has finished sending
    client.close();
  });

  sleep(1);
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="metadata">Metadata&lt;/h1>
&lt;p>The &lt;code>Metadata&lt;/code> is an object that represents the gRPC stream&amp;rsquo;s message.&lt;/p>
&lt;section class="expand-table-wrapper">&lt;div class="button-div">
&lt;button class="expand-table-btn">Expand table&lt;/button>
&lt;/div>&lt;div class="responsive-table-wrapper">
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>Metadata.ts&lt;/code>&lt;/td>
&lt;td>number&lt;/td>
&lt;td>Contains the timestamp of the original event. For example, when a message has been received.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/section>&lt;h3 id="example">Example&lt;/h3>
&lt;div class="code-group" data-props='{"labels": ["A handler metadata example"], "lineNumbers": [true]}'>
&lt;div class="code-snippet ">&lt;div class="lang-toolbar">
&lt;span class="lang-toolbar__item lang-toolbar__item-active">JavaScript&lt;/span>
&lt;span class="code-clipboard">
&lt;button x-data="app_code_snippet()" x-init="init()" @click="copy()">
&lt;img class="code-clipboard__icon" src="/media/images/icons/icon-copy-small-2.svg" alt="Copy code to clipboard" width="14" height="13">
&lt;span>Copy&lt;/span>
&lt;/button>
&lt;/span>
&lt;div class="lang-toolbar__border">&lt;/div>
&lt;/div>&lt;div class="code-snippet ">
&lt;pre data-expanded="false">&lt;code class="language-javascript">import { Client, Stream } from &amp;#39;k6/net/grpc&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;
const client = new Client();
client.load([], &amp;#39;../../grpc_server/route_guide.proto&amp;#39;);
export default () =&amp;gt; {
if (__ITER == 0) {
client.connect(&amp;#39;127.0.0.1:10000&amp;#39;, { plaintext: true });
}
const stream = new Stream(client, &amp;#39;main.RouteGuide/RecordRoute&amp;#39;);
// sets up a handler for the data (server sends data) event
stream.on(&amp;#39;data&amp;#39;, (stats, metadata) =&amp;gt; {
console.log(&amp;#39;It took&amp;#39;, stats.elapsedTime, &amp;#39;seconds&amp;#39;);
console.log(&amp;#39;This message has been received:&amp;#39;, metadata.ts);
});
stream.on(&amp;#39;end&amp;#39;, function () {
// The server has finished sending
client.close();
});
sleep(1);
};&lt;/code>&lt;/pre>
&lt;/div>
&lt;/div>
&lt;/div></description></item></channel></rss>