This Subscribe message is currently only useful if:
you have your own backend using websocket for users presence in a room
you configured reliableTransport and unreliableTransport to use a function the send to your backend websocket for naf networked updates, chat, your own join/left messages.
you use a modified version naf-janus-adapter master with the syncOccupants api to sync subscriptions to publishers via the new createListener and to not create a publisher connection for you so that all participants don't subscribe automatically to you that make explode the number of connections the server needs to maintain. In the experiment https://github.com/networked-aframe/naf-janus-adapter/pull/9 I only created the createListener function. Also be aware of https://github.com/networked-aframe/naf-janus-adapter/issues/21 that is not fixed yet.
datachannels reliable and unreliable are used in both direction send/receive on the main connection. The other subscriber connections don't have datachannels, only audio and video tracks.
the Subscribe message is exactly the same as Join with {media: UserId} except it doesn't has the listener user_id or room_id, and we don't maintain a list of them in the switchboard.
It would be more useful if we do the following changes instead:
remove this Subscribe message code completely
modify the Join message to add a kind field {kind: ["publisher"|"listener"|"subscriber"], data: true, notifications: true} (add JoinKind::Listener)
maintain a list of listeners in switchboard (add switchboard.join_listener)
in process_join, if listener, use switchboard.join_listener and send to all publishers and listeners { "event": "join", "kind": "listener", "user_id": user_id, "room_id": room_id }, if publisher, send with the event with "kind": "publisher". In naf janus adapter, you can subscribe to their audio/video if "kind": "publisher", otherwise just maintain a list of listeners or counter of listeners in the room.
in switchboard rename get_all_users to get_publishers, add a new get_listeners
in switchboard, new users_occupying similar to publishers_occupying but return publishers and listeners
in switchboard data_recipients_for, use users_occupying instead of publishers_occupying
in process_join response send the list of publishers in users array as today + listeners array: {"users:": ["publisherId1", "publisherId2"], "listeners": ["listenerId1", "listenerId2"]} (rename users to publishers if we don't care about backward compatibility, also modify the initialOccupants line in the adapter that add those publishers to the available occupants to subscribe)
stop using data:true to detect if the connection is a publisher and look at kind: "publisher" field (we can fallback to using data:true if kind is not defined if we care about backward compatibility)
in process_data and destroy_session (leave event), process_join (join event), instead of using switchboard.publishers_occupying use switchboard.users_occupying that returns both publishers and listeners. In destroy_session, add the kind: "publisher"|"listener" field to the leave event. Also probably fix sending the leave event if the main connection is closed and not all connections to fix https://github.com/networked-aframe/naf-janus-adapter/issues/21. This way naf adapter can unsubscribe if the participant was publisher, remove the participant for the users list if publisher or listener.
message Switch {kind: ["publisher"|"listener"]} to switch the main connection to publisher or back to listener, send a switch event to all publishers and listeners so they can subscribe if it became a publisher or unsubscribe if it became a listener. (switchboard.switch_to_publisher, switchboard.switch_to_listener)
Changes in naf adapter master branch that maintain a separate availableOccupants and occupants lists and syncOccupants api:
create the main connection (the one created currently with the this.createPublisher() call) with Join message kind: "listener" or kind: "publisher"
modify createSubscriber to add kind:subscriber
create a function sendSwitch with param kind: "publisher"|"listener" that send the switch event.
listener for the switch event, more or less treat it like a leave followed by a join
optional: option to not send unreliable data (networked updates) if kind listener so you can be a ghost avatar in a room and listen to publishers, you can still chat with the reliable transport (can be over datachannel or websocket)
modify availableOccupants to have the information of publisher or listener or two separate arrays.
in your project, instead of using adapter.requestedOccupants = adapter.availableOccupants;, use adapter.requestedOccupants = [] and maintain the list of occupants (publishers) you want to subscribe to, for example based on a private audio zone you are in.
in the join and leave event handlers, emit a similar event so we can add (if the user is in your private audio zone) or remove the occupant if kind publisher from the requestedOccupants array and call syncOccupants(). Note: the call syncOccupants() in the join handler in the adapter is not really useful here because we don't use an external users list backend and are not calling syncOccupants(newOccupants) when the users list change.
This way, you can use the plugin without any additional backend, you can also choose to keep reliableTransport/unreliableTransport to datachannel or websocket, and keep networked updates and chat on it.
Note: the server still maintain a WebRTC connection for the participant, even if the participant don't use datachannel, audio or video. We can probably remove creation of the datachannels if reliableTransport and unreliableTransport are not set to "datachannel" (this is the default, so meaning you set it to "websocket"), but we still keep a main WebRTC connection with an inactive audio track and an inactive video track.
Reenable subscribe message that was commented in #2 and add proper JWT check. This closes https://github.com/mozilla/janus-plugin-sfu/issues/83 and https://github.com/mozilla/janus-plugin-sfu/pull/86
This is to support use case like 1-5 publishers and 100 listeners for some sort of webinar, see discussion in https://github.com/mozilla/janus-plugin-sfu/issues/76
This Subscribe message is currently only useful if:
syncOccupants
api to sync subscriptions to publishers via the newcreateListener
and to not create a publisher connection for you so that all participants don't subscribe automatically to you that make explode the number of connections the server needs to maintain. In the experiment https://github.com/networked-aframe/naf-janus-adapter/pull/9 I only created thecreateListener
function. Also be aware of https://github.com/networked-aframe/naf-janus-adapter/issues/21 that is not fixed yet.Having written the above, rewritten the api documentation, reading again my comments on https://github.com/mozilla/janus-plugin-sfu/issues/76 and knowing that
Subscribe
message is exactly the same asJoin
with{media: UserId}
except it doesn't has the listener user_id or room_id, and we don't maintain a list of them in the switchboard.It would be more useful if we do the following changes instead:
Subscribe
message code completely{kind: ["publisher"|"listener"|"subscriber"], data: true, notifications: true}
(addJoinKind::Listener
)switchboard.join_listener
)process_join
, if listener, useswitchboard.join_listener
and send to all publishers and listeners{ "event": "join", "kind": "listener", "user_id": user_id, "room_id": room_id }
, if publisher, send with the event with"kind": "publisher"
. In naf janus adapter, you can subscribe to their audio/video if"kind": "publisher"
, otherwise just maintain a list of listeners or counter of listeners in the room.get_all_users
toget_publishers
, add a newget_listeners
users_occupying
similar topublishers_occupying
but return publishers and listenersdata_recipients_for
, useusers_occupying
instead ofpublishers_occupying
process_join
response send the list of publishers in users array as today + listeners array:{"users:": ["publisherId1", "publisherId2"], "listeners": ["listenerId1", "listenerId2"]}
(rename users to publishers if we don't care about backward compatibility, also modify theinitialOccupants
line in the adapter that add those publishers to the available occupants to subscribe)data:true
to detect if the connection is a publisher and look atkind: "publisher"
field (we can fallback to usingdata:true
if kind is not defined if we care about backward compatibility)process_data
anddestroy_session
(leave event),process_join
(join event), instead of usingswitchboard.publishers_occupying
useswitchboard.users_occupying
that returns both publishers and listeners. Indestroy_session
, add thekind: "publisher"|"listener"
field to the leave event. Also probably fix sending the leave event if the main connection is closed and not all connections to fix https://github.com/networked-aframe/naf-janus-adapter/issues/21. This way naf adapter can unsubscribe if the participant was publisher, remove the participant for the users list if publisher or listener.{kind: ["publisher"|"listener"]}
to switch the main connection to publisher or back to listener, send aswitch
event to all publishers and listeners so they can subscribe if it became a publisher or unsubscribe if it became a listener. (switchboard.switch_to_publisher
,switchboard.switch_to_listener
)Changes in naf adapter master branch that maintain a separate
availableOccupants
andoccupants
lists andsyncOccupants
api:this.createPublisher()
call) with Join messagekind: "listener"
orkind: "publisher"
createSubscriber
to addkind:subscriber
sendSwitch
with paramkind: "publisher"|"listener"
that send theswitch
event.switch
event, more or less treat it like a leave followed by a joinavailableOccupants
to have the information of publisher or listener or two separate arrays.adapter.requestedOccupants = adapter.availableOccupants;
, useadapter.requestedOccupants = []
and maintain the list of occupants (publishers) you want to subscribe to, for example based on a private audio zone you are in.requestedOccupants
array and callsyncOccupants()
. Note: the callsyncOccupants()
in the join handler in the adapter is not really useful here because we don't use an external users list backend and are not callingsyncOccupants(newOccupants)
when the users list change.This way, you can use the plugin without any additional backend, you can also choose to keep reliableTransport/unreliableTransport to datachannel or websocket, and keep networked updates and chat on it. Note: the server still maintain a WebRTC connection for the participant, even if the participant don't use datachannel, audio or video. We can probably remove creation of the datachannels if reliableTransport and unreliableTransport are not set to "datachannel" (this is the default, so meaning you set it to "websocket"), but we still keep a main WebRTC connection with an inactive audio track and an inactive video track.