-
Notifications
You must be signed in to change notification settings - Fork 5
Stream
Regarding the handling of streams, basically, we just need to be aware of the handle_stream/4
callback function and the stream_send/3
function on the handler.
@impl Requiem
def handle_stream(stream_id, data, conn, state) do
stream_send(stream_id, data, false)
{:ok, conn, state}
end
However, you need to be careful with the stream_id.
The above example may fail.
The lower bits of stream_id change under the following conditions.
- Whether it was created by the client or the server
- Bidirectional or unidirectional.
(See: https://datatracker.ietf.org/doc/html/rfc9000#section-2.1)
If you try to send data from the server side using send_stream through a unidirectional stream created by the client, an exception will be thrown.
Here are two utilities.
It is possible to check the nature of the stream_id in the following way.
-
bidi
meansbidirectional
-
uni
meansunidirectional
Requiem.StreamId.is_bidi?(stream_id)
Requiem.StreamId.is_uni?(stream_id)
Requiem.StreamId.is_server_initiated?(stream_id)
Requiem.StreamId.is_client_initiated?(stream_id)
If you just want to know if it can be read or written, you can also write the following.
Requiem.StreamId.is_readable?(stream_id)
Requiem.StreamId.is_writable?(stream_id)
It is also possible to create a new stream on the server side. To do so, use stream_open/2
.
The first argument is a boolean indicating whether it is bidirectional or not, and the second argument is an arbitrary string to be used for identification or message relay when the result of stream_open/2
is received in an asynchronous message.
@impl Requiem
def handle_stream(stream_id, data, conn, state) do
stream_open(false, "NEW_UNI_STREAM" <> data)
{:ok, new_conn, state}
end
@impl Request
def handle_info({:stream_open, stream_id, message}, conn, state) do
stream_send(stream_id, message, false)
{:noreply, conn, state}
end
Then, as in the example above, handle_info
can receive the results of stream_open.
The newly prepared stream_id is included as an argument, which can be used to send a message to the client using stream_send
.