-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Specify behavior when multiple controlling pages are connected to the session #19
Comments
Noted as an issue in the "Usage on Remote Screen" section in the spec: http://w3c.github.io/presentation-api/#usage-on-remote-screen |
Adding to this issue from #36 discussion of how messaging should be done between the presentation and multiple connected sessions. In some scenarios the presented page may have active connections to multiple PresentationSessions on other pages. In a gaming scenario, each connected session would represent a game player. Some information (like dealing a card into the hand) should be sent to one player, while other information (playing a card face up) should be sent to all players. We need to specify:
Note this thread discussing some concrete spec changes to facilitate this case. |
The |
Agreed with @jakearchibald on that. Would you @mfoltzgoogle with help from @drott like to investigate this further? |
PROPOSED RESOLUTION: starting point for #19 is Promise NP.getSession(), PresentationSession[] NP.getSessions(), NP.onsessionavailable event when set of sessions changes (with possible naming changes) See related discussion at F2F in Berlin: |
ACTION: @mfoltzgoogle to look at renaming "sessions" for controlling and presenting sides. [recorded in http://www.w3.org/2015/05/19-webscreens-minutes.html#action12] ACTION: @mfoltzgoogle to fix spec to refer to updated Presentation idiom [recorded in http://www.w3.org/2015/05/19-webscreens-minutes.html#action13] |
Also, should define the mechanism by which the page can create a new session that can access existing presentation. |
How about the following spec change for the multiple connections? It's based on the assumption that only one controller can connect to the presentation page at a time. If the page is slow handling each controller, the UA can simply queue them and resolve the next call to partial interface NavigatorPresentation {
Promise<PresentationSession> requestController(); // replaces navigator.presentation.session
} Then a simple presentation page supporting one controller would need to write something like this: navigator.presentation.requestController().then(handleController);
var handleController = function(controller) {
controller.onstatechange = function(e) {
if (e.state == "connected") {
controller.onmessage = function(e) {
showMessage("Received message " + e.msg);
};
} else if (e.state == "disconnected") {
// wait for the controller to connect back
navigator.presentation.requestController().then(handleController);
} else if (e.state == "terminated") {
// nothing to do, the page is being closed, for the sake of completeness
}
};
}); And code for the page supporting multiple controllers would look like this: // controllers
var mControllers = [];
// maximum number of controllers to join the presentation
var MAX_CONTROLLERS = 5;
// announce that the page is ready to become a presentation and receive its first controller
// assume that only one controller can start the presentation or connect to it at the time
navigator.presentation.requestController().then(handleControllerAdded);
var handleControllerAdded = function(controller) {
showMessage("Controller added: " + controller.id);
// assert controller.state == "connecting";
controller.onstatechange = function(e) {
if (e.state == "connected") {
handleControllerConnection(this)
} else if (e.state == "disconnected" || e.state == "terminated") {
handleControllerDisconnection(this);
}
};
};
var handleControllerConnection = function(controller) {
if (mControllers.empty()) {
setUp();
}
mControllers.add(controller);
controller.onmessage = function(e) {
showMessage("Received message " + e.msg + " from " + this.id);
};
if (mControllers.length < MAX_CONTROLLERS) {
navigator.presentation.requestController(handleController);
}
};
var handleControllerDisconnection = function(controller) {
mControllers.remove(controller);
if (mControllers.empty()) {
shutDown();
} else if (mControllers.length < MAX_CONTROLLERS) {
navigator.presentation.requestController(handleController);
}
};
var setUp = function() {
showMessage("The presentation is connected");
};
var shutDown = function() {
showMessage("No controllers, please connect.");
navigator.presentation.requestController(handleController);
}; The semantic of the method is as following:
|
+1. Just one comment about naming what about getNextSession or gerNextConnection instead of getNextController? We deceided to use the term controller for the opening page. |
Session to me is an interface exposed to the controller page to communicate with a presentation. |
@avayvod Regarding the API proposal: During the F2F we proposed the following API, in part to ensure that the common use case is simple, and to follow the example of ServiceWorker getRegistration/getRegistrations [1]. Something like the following:
In your example I had the following questions:
|
I haven't found any examples of using getRegistration() and getRegistrations() on HTML5Rocks or MDN or in the API draft. From the algorithm description linked it seems that getRegistration() is used to get a registration for ServiceWorker with a known scope URL, while getRegistrations() is an enumeration method to query all registrations available. There's also no event to notify the page when a new registration is available. IMHO, it doesn't match what's needed by the Presentation API... (get the session for the initial controller page and get the rest of them as they connect). Answers to the questions:
The questions I have about the proposed resolution:
partial interface NavigatorPresentation {
Promise<PresentationContext> presentationContext();
}
interface PresentationContext : EventTarget {
readonly attribute PresentationSession[] sessions;
attribute EventHandler onsessionavailable;
};
My example using the proposed resolution from F2F would look something like: // controlling pages that successfully connected
var mSessions = [];
// maximum number of sessions to join the presentation
var MAX_SESSIONS = 5;
// announce that the page is ready to become a presentation and receive the controllers that are
// already connected or connecting
// NOTE: if knowning the initial controller is important, the page must first call getSession() and execute
// the call below in the promise resolution handler:
// var initialSession = null;
// navigator.presentation.getSession().then(function (firstSession) {
// initialSession = firstSession;
navigator.presentation.getSessions().then(handleSessionsAdded);
var handleSessionsAdded = function(sessions) {
// page could get more than the maximum supported number of sessions received in getSessions()
for (var i = 0; i < min(sessions.length, MAX_SESSIONS); i++)
handleSessionAdded(sessions[i]);
navigator.presentation.onsessionavailable = function(evt) {
if (mSessions.length == MAX_SESSIONS) evt.preventDefault();
handleSessionAdded(evt.session);
};
};
var handleSessionAdded = function(session) {
showMessage("Session added: " + session.id);
// assert session.state == "connecting";
session.onstatechange = function(e) {
if (e.state == "connected") {
handleSessionConnection(this)
} else if (e.state == "disconnected" || e.state == "terminated") {
handleSessionDisconnection(this);
}
};
};
var handleSessionConnection = function(session) {
if (mControllers.empty()) {
setUp();
}
mSessions.add(sessions);
session.onmessage = function(e) {
showMessage("Received message " + e.msg + " from " + this.id);
};
};
var handleSessionDisconnection = function(session) {
mSessions.remove(session);
if (mSessions.empty()) {
shutDown();
}
};
var setUp = function() {
showMessage("The presentation is connected");
};
var shutDown = function() {
showMessage("No controllers, please connect.");
}; |
Why does
I actually had in mind only presenting page that was started as a result of a call to |
Let me see if I can formulate another proposal that addresses the concerns raised here. The other actions raised in the F2F to formulate new idioms and a new APIs for referring to the PresentationSession on either side of the presentation [1] [2] I will consider and propose separately. [1] http://www.w3.org/2015/05/19-webscreens-minutes.html#action12 |
We might want to support the following functionality on the presenting page:
From that perspective simple interface that was proposed by @avayvod could be a good solution.
Additionally, we will have to pass implementation specific parameters to Another thing is that on the controlling page it would not be possible to differentiate that presentation page is not accepting connections anymore, see communication issues listed here: #67 (comment). Establishing of the connection (pairing) is working I the same way for Samsung's multiscreen and the same issues exist for that technology. In practice, requirements 2 and 3 would difficult to implement for controlling page. So presenting page would be better off establishing connection, sending message that no more participants are accepted and closing that immediately. |
|
Agree on 1, 2, 3, 5.
|
This seems to have been resolved. Closing. |
An implication of reconnection is that multiple pages may connect to the same presentation. The behavior of the API should be defined for this scenario. Specifically,
onstatechange
="connected"
/"disconnected"
on both sidesclose()
on both sidesThe text was updated successfully, but these errors were encountered: