View Source PubSub
PubSub (Publish-Subscribe) is a messaging pattern where clients publish messages to channels, and other clients subscribed to those channels receive and react to the messages in real time. Tamnoon provides built-in PubSub functionality, enabling communication between multiple clients.
In Tamnoon's case:
Clients publish method calls to channels.
Other clients subscribed to those channels will receive and execute the method calls.
Clients can subscribe and unsubscribe from channels dynamically.
This allows for real-time interaction between clients - ideal for collaborative apps, chat rooms, live dashboards, and more.
Example
If a client publishes an :add_message method to the channel "room_123", all clients subscribed to "room_123" will receive and execute the :add_message method.
Channels
When publishing method calls, they are sent to a specific channel. Clients can dynamically join or leave channels using the built-in :sub and :unsub methods, and view their current subscribed channels using Tamnoon.Methods.subbed_channels/0.
:subsubscribes the client to a channel.:unsubunsubscribes the client from a channel.Both methods expect a channel name passed in as
req["channel"].
Channels are automatically created when a client attempts to subscribe to one that doesn't exist.
The clients channel
All clients are automatically subscribed to a special channel named
"clients". This channel is non-leavable.
Example
defmethod :switch_room do
target_room_id = req["value"]
Tamnoon.Methods.unsub(%{"channel" => "room_\#{state[:current_room_id]}"}, state)
Tamnoon.Methods.sub(%{"channel" => "room_\#{target_room_id}"}, state)
{%{current_room_id: target_room_id}}
endIn the example above:
The client leaves their current room channel (e.g.,
"room_1").Then joins the new room channel (e.g.,
"room_2").The client's state is updated to reflect the new
current_room_id.
Manual invocation of PubSub methods
Unlike other methods, PubSub methods (
:sub,:unsuband:pub) just trigger a side effect. This means that when using the manual invocation syntax, there is no need to return their return value from the method, and it can be safely ignored.
Publishing
In Tamnoon, clients communicate with each other by publishing method calls. These calls are broadcast to a specified channel, where all clients subscribed to that channel (including the sender) will receive and execute the method as if they triggered it themselves.
To publish a method call, use the built-in :pub method, which accepts:
"channel"- the name of the channel to publish to."action"- a map containing:"method"- the method name to call.Any additional data to pass along via req.
Example
defmethod :send_message do
%{
current_message: current_message,
current_room_id: current_room_id
} = state
Tamnoon.Methods.pub(%{
"channel" => "room_#{current_room_id}",
"action" => %{
"method" => "add_message",
"message" => current_message
}
}, state)
{%{current_message: ""}}
endWhat this does:
Publishes a call to the
:add_messagemethod on the channel for the current room.All clients in that room (including the sender) will receive and run
:add_message.The message content is sent as
req["message"].
Clears the
:current_messagestate field on the sender's side only (clean-up).
This is a common pattern in Tamnoon:
One method (e.g.,
:send_message) handles logic only the publisher needs (validation, cleanup, etc.).It then publishes another method (e.g.,
:add_message) that contains logic for all clients in the channel.