An OTP library to send and receive real time events over HTTP connections.
In your rebar.config file, add the dependency:
{deps, [
{nrte, {git, "git@github.com:nomasystems/nrte.git", {branch, "main"}}}
]}.And start listening to incoming connections:
nrte:start_listening(#{} = Opts).Then, you can connect either via WebSocket or server-sent events to start receiving messages for the given topics.
For example, in javascript via the WebSocket interface:
const webSocket = new WebSocket('ws://localhost:2080/websocket?topics=topic1;topic2;topic3');Or via server-sent events in curl:
curl 'localhost:2080/eventsource?topics=topic1;topic2;topic3'Then, all data posted to the /message endpoint will be redirected to the online subscribers:
curl -X POST -d 'my custom message' 'localhost:2080/message?topics=topic1'All the keys in the nrte:start_listening/1 parameter are optional and default to the following values:
#{
auth_type => {always_allow, all}},
name => nrte_listener,
port => 2080,
serve_priv_dir => false
}auth_type: see authentication for details.name: a unique name to be registered as the server.port: TCP port that serves the different endpoints.serve_priv_dir: whether to include the priv dir in the server or not.
It's also possible to define a global data_template with application:set_env(nrte, data_template, Template). Defaults to {data_tempate, {<<"{{topic}};{{message}}">>}} and any appearance of {{topic}} and {{message}} are replaced with the actual values.
By default nrte doesn't authenticate its users, but this can be changed by setting the auth_type option to a tuple {auth_mod, Mod}. In that case, when a request arrives, nrte will call Mod:nrte_auth(Headers) and use the returned nrte_auth_value() to allow or deny access to the resource. See the nrte_auth module for the behaviour to implement.
Some examples:
% Wrong credentials; results in a 401
nrte_auth(_Headers) ->
unauthorized.
% Disallow access to all topics; results in a 403
nrte_auth(_Headers) ->
none.
% Allow access to all topics
nrte_auth(_Headers) ->
all.
% Allow access to subscribe to some topics but disallow publishing
nrte_auth(_Headers) ->
#{allowed_publications => none,
allowed_subscriptions => ["allowed_topic_prefix.*", "other_topic"]}.Messages can also be published via nrte:publish/2 and subscribed from nrte:subscribe/1. In the latter case, the caller will receive messages in the form of {nrte_message, Data}:
> nrte:subscribe([<<"example">>]).
ok
> nrte:publish(<<"example:subexample">>, <<"my-message">>).
ok
> receive {nrte_message, Data} -> Data end.
<<"example:subexample;my-message">>When a client connects to the /websocket or /eventsource endpoints, a special message will be published to the topic nrte:subscription_init:{{source}} with the client subscribed topics as message. When a client disconnects from that endpoint, a similar message will be published as nrte:subscription_terminate:{{source}}. It is then possible to subscribe to these special topics and receive the messages. For example:
{nrte_message,<<"nrte:subscription_init:websocket;topic1">>}
{nrte_message,<<"nrte:subscription_terminate:websocket;topic1">>}
{nrte_message,<<"nrte:subscription_init:eventsource;topic1;topic2;topic3">>}
{nrte_message,<<"nrte:subscription_terminate:eventsource;topic1;topic2;topic3">>}Any doubt or suggestion? Please, check out our issue tracker.
Pull requests are welcome. Please read the contributing guidelines to know more about contribution.