Code matching tutorials
This commit is contained in:
parent
4fbf9a6a6e
commit
442499bf01
@ -1,21 +1,22 @@
|
||||
var OV;
|
||||
var session;
|
||||
var publisher;
|
||||
var sessionId;
|
||||
var audioEnabled = true;
|
||||
var videoEnabled = true;
|
||||
var numOfVideos = 0;
|
||||
var OV; // OpenVidu object to initialize a session
|
||||
var session; // Session object where the user will connect
|
||||
var publisher; // Publisher object which the user will publish
|
||||
var sessionId; // Unique identifier of the session
|
||||
var audioEnabled = true; // True if the audio track of publisher is active
|
||||
var videoEnabled = true; // True if the video track of publisher is active
|
||||
var numOfVideos = 0; // Keeps track of the number of videos that are being shown
|
||||
|
||||
|
||||
// Check if the URL already has a room
|
||||
window.addEventListener('load', function () {
|
||||
sessionId = window.location.hash;
|
||||
sessionId = window.location.hash; // For 'https://myurl/#roomId', sessionId would be '#roomId'
|
||||
if (sessionId) {
|
||||
// The URL has a session id
|
||||
// The URL has a session id. Join the room right away
|
||||
console.log("Joining to room " + sessionId);
|
||||
showSessionHideJoin();
|
||||
joinRoom(sessionId);
|
||||
} else {
|
||||
// The URL has not a session id. Show welcome page
|
||||
showJoinHideSession();
|
||||
}
|
||||
});
|
||||
@ -38,11 +39,11 @@ function joinRoom(sessionId) {
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with a sessionId ---
|
||||
|
||||
// Init OpenVidu object
|
||||
OV = new OpenVidu();
|
||||
|
||||
// We will join the video-call "sessionId". This parameter must start with the URL of OpenVidu Server, with secure WebSocket protocol ('wss://')
|
||||
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + '?secret=MY_SECRET');
|
||||
// We will join the video-call "sessionId". As there's no server, this parameter must start with the URL of
|
||||
// OpenVidu Server (with secure websocket protocol: "wss://") and must include the OpenVidu secret at the end
|
||||
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + "?secret=MY_SECRET");
|
||||
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
@ -51,6 +52,7 @@ function joinRoom(sessionId) {
|
||||
session.on('streamCreated', function (event) {
|
||||
// Subscribe to the Stream to receive it. HTML video will be appended to element with 'subscriber' id
|
||||
var subscriber = session.subscribe(event.stream, 'videos');
|
||||
// When the new video is added to DOM, update the page layout to fit one more participant
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
numOfVideos++;
|
||||
updateLayout();
|
||||
@ -59,6 +61,7 @@ function joinRoom(sessionId) {
|
||||
|
||||
// On every new Stream destroyed...
|
||||
session.on('streamDestroyed', function (event) {
|
||||
// Update the page layout
|
||||
numOfVideos--;
|
||||
updateLayout();
|
||||
});
|
||||
@ -66,8 +69,7 @@ function joinRoom(sessionId) {
|
||||
|
||||
// --- 3) Connect to the session ---
|
||||
|
||||
// 'token' param irrelevant when using insecure version of OpenVidu. Second param will be received by every user
|
||||
// in Stream.connection.data property, which will be appended to DOM as the user's nickname
|
||||
// Remember 'userId' param (usually called 'token') is irrelevant when using the insecure version of OpenVidu
|
||||
session.connect(userId, function (error) {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
@ -82,9 +84,10 @@ function joinRoom(sessionId) {
|
||||
});
|
||||
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
// When your own video is added to DOM, update the page layout to fit it
|
||||
numOfVideos++;
|
||||
updateLayout();
|
||||
$(event.element).prop('muted', true);
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
@ -96,9 +99,11 @@ function joinRoom(sessionId) {
|
||||
}
|
||||
});
|
||||
|
||||
// Update the URL shown in the browser's navigation bar to show the session id
|
||||
var pathname = (location.pathname.slice(-1) === "/" ? location.pathname : location.pathname+"/");
|
||||
window.history.pushState("", "", pathname + sessionId);
|
||||
|
||||
// Auxiliary methods to show the session's view
|
||||
showSessionHideJoin();
|
||||
initializeSessionView();
|
||||
|
||||
@ -107,7 +112,7 @@ function joinRoom(sessionId) {
|
||||
|
||||
|
||||
function leaveRoom() {
|
||||
|
||||
|
||||
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
session.disconnect();
|
||||
|
||||
|
||||
@ -46,15 +46,18 @@ public class LoginController {
|
||||
public ResponseEntity<Object> login(@RequestBody String userPass, HttpSession httpSession) throws ParseException {
|
||||
|
||||
System.out.println("Logging in | {user, pass}=" + userPass);
|
||||
// Retrieve params from POST body
|
||||
JSONObject userPassJson = (JSONObject) new JSONParser().parse(userPass);
|
||||
String user = (String) userPassJson.get("user");
|
||||
String pass = (String) userPassJson.get("pass");
|
||||
|
||||
if (login(user, pass)) {
|
||||
System.out.println("'" + user + "' has logged in");
|
||||
if (login(user, pass)) { // Correct user-pass
|
||||
// Validate session and return OK
|
||||
// Value stored in HttpSession allows us to identify the user in future requests
|
||||
httpSession.setAttribute("loggedUser", user);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} else {
|
||||
} else { // Wrong user-pass
|
||||
// Invalidate session and return error
|
||||
httpSession.invalidate();
|
||||
return new ResponseEntity<>("User/Pass incorrect", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@ -51,10 +51,18 @@ public class SessionController {
|
||||
System.out.println("Getting sessionId and token | {sessionName}=" + sessionNameParam);
|
||||
|
||||
JSONObject sessionJSON = (JSONObject) new JSONParser().parse(sessionNameParam);
|
||||
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
String sessionName = (String) sessionJSON.get("session");
|
||||
|
||||
// Role associated to this user
|
||||
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
|
||||
|
||||
// Optional data to be passed to other users when this user connects to the video-call
|
||||
// In this case, a JSON with the value we stored in the HttpSession object on login
|
||||
String serverData = "{\"serverData\": \"" + httpSession.getAttribute("loggedUser") + "\"}";
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
TokenOptions tokenOptions = new TokenOptions.Builder().data(serverData).role(role).build();
|
||||
|
||||
JSONObject responseJson = new JSONObject();
|
||||
@ -63,16 +71,25 @@ public class SessionController {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
System.out.println("Existing session " + sessionName);
|
||||
try {
|
||||
|
||||
// Get the existing sessionId from our collection with
|
||||
// the sessionName param ("TUTORIAL")
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
|
||||
|
||||
|
||||
// Update our collection storing the new token
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
|
||||
|
||||
// Prepare the response with the sessionId and the token
|
||||
responseJson.put(0, sessionId);
|
||||
responseJson.put(1, token);
|
||||
|
||||
|
||||
// Return the response to the client
|
||||
return new ResponseEntity<>(responseJson, HttpStatus.OK);
|
||||
|
||||
} catch (Exception e) {
|
||||
// If error generate an error message and return it to client
|
||||
return getErrorResponse(e);
|
||||
}
|
||||
|
||||
@ -80,19 +97,28 @@ public class SessionController {
|
||||
// New session: return a new sessionId and token
|
||||
System.out.println("New session " + sessionName);
|
||||
try {
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
Session session = this.openVidu.createSession();
|
||||
// Get the sessionId
|
||||
String sessionId = session.getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = session.generateToken(tokenOptions);
|
||||
|
||||
// Store the session and the token in our collections
|
||||
this.mapSessions.put(sessionName, session);
|
||||
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
|
||||
// Prepare the response with the sessionId and the token
|
||||
responseJson.put(0, sessionId);
|
||||
responseJson.put(1, token);
|
||||
|
||||
// Return the response to the client
|
||||
return new ResponseEntity<>(responseJson, HttpStatus.OK);
|
||||
|
||||
} catch (Exception e) {
|
||||
// If error generate an error message and return it to client
|
||||
return getErrorResponse(e);
|
||||
}
|
||||
}
|
||||
@ -109,30 +135,36 @@ public class SessionController {
|
||||
}
|
||||
System.out.println("Removing user | {sessionName, token}=" + sessionNameToken);
|
||||
|
||||
// Retrieve the params from BODY
|
||||
JSONObject sessionNameTokenJSON = (JSONObject) new JSONParser().parse(sessionNameToken);
|
||||
String sessionName = (String) sessionNameTokenJSON.get("sessionName");
|
||||
String token = (String) sessionNameTokenJSON.get("token");
|
||||
|
||||
// If the session exists ("TUTORIAL" in this case)
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
|
||||
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
|
||||
// If the token exists
|
||||
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
|
||||
// User left the session
|
||||
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
|
||||
// Last user left the session
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} else {
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
} else {
|
||||
// The SESSIONID wasn't valid
|
||||
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
} else {
|
||||
// The SESSION does not exist
|
||||
System.out.println("Problems in the app server: the SESSION does not exist");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ function joinSession() {
|
||||
};
|
||||
initMainVideo(event.element, userData);
|
||||
appendUserData(event.element, userData);
|
||||
$(event.element).prop('muted', true);
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
|
||||
@ -116,17 +116,18 @@ function leaveSession() {
|
||||
|
||||
|
||||
|
||||
/* APPLICATION BACKEND METHODS */
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
function logIn() {
|
||||
var user = $("#user").val();
|
||||
userName = user;
|
||||
var pass = $("#pass").val();
|
||||
var jsonBody = JSON.stringify({
|
||||
var user = $("#user").val(); // Username
|
||||
var pass = $("#pass").val(); // Password
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'user': user,
|
||||
'pass': pass
|
||||
});
|
||||
|
||||
userName = user;
|
||||
|
||||
httpRequest('POST', 'api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
|
||||
console.warn(userName + ' login');
|
||||
$("#name-user").text(user);
|
||||
@ -147,26 +148,30 @@ function logOut() {
|
||||
}
|
||||
|
||||
function getSessionIdAndToken(callback) {
|
||||
nickName = $("#participantName").val();
|
||||
sessionName = $("#sessionName").val();
|
||||
var jsonBody = JSON.stringify({
|
||||
sessionName = $("#sessionName").val(); // Video-call chosen by the user
|
||||
nickName = $("#participantName").val(); // Nickname chosen by the user
|
||||
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'session': sessionName
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
|
||||
sessionId = response[0];
|
||||
token = response[1];
|
||||
sessionId = response[0]; // Get sessionId from response
|
||||
token = response[1]; // Get token from response
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
|
||||
callback();
|
||||
callback(); // Continue the join operation
|
||||
});
|
||||
}
|
||||
|
||||
function removeUser() {
|
||||
// Body of POST request with the name of the session and the token of the leaving user
|
||||
var jsonBody = JSON.stringify({
|
||||
'sessionName': sessionName,
|
||||
'token': token
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
|
||||
console.warn(userName + " correctly removed from session");
|
||||
});
|
||||
@ -195,7 +200,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
/* APPLICATION BACKEND METHODS */
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
|
||||
|
||||
|
||||
@ -27,11 +27,11 @@ function joinSession() {
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
|
||||
// Add a new <p> element for the user's name and nickname just below its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
});
|
||||
});
|
||||
@ -42,6 +42,7 @@ function joinSession() {
|
||||
removeUserData(event.stream.connection);
|
||||
});
|
||||
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
@ -73,7 +74,7 @@ function joinSession() {
|
||||
};
|
||||
initMainVideo(event.element, userData);
|
||||
appendUserData(event.element, userData);
|
||||
$(event.element).prop('muted', true);
|
||||
$(event.element).prop('muted', true); // Mute lcoal video
|
||||
});
|
||||
|
||||
|
||||
@ -116,18 +117,19 @@ function leaveSession() {
|
||||
|
||||
|
||||
|
||||
/* APPLICATION BACKEND METHODS */
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
function logIn() {
|
||||
var user = $("#user").val();
|
||||
userName = user;
|
||||
var pass = $("#pass").val();
|
||||
var jsonBody = JSON.stringify({
|
||||
var user = $("#user").val(); // Username
|
||||
var pass = $("#pass").val(); // Password
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'user': user,
|
||||
'pass': pass
|
||||
});
|
||||
|
||||
httpRequest('POST', 'api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
|
||||
userName = user;
|
||||
|
||||
httpRequest('POST', '/api-login/login', jsonBody, 'Login WRONG', function successCallback(response){ // Send POST request
|
||||
console.warn(userName + ' login');
|
||||
$("#name-user").text(user);
|
||||
$("#not-logged").hide();
|
||||
@ -147,26 +149,29 @@ function logOut() {
|
||||
}
|
||||
|
||||
function getSessionIdAndToken(callback) {
|
||||
nickName = $("#participantName").val();
|
||||
sessionName = $("#sessionName").val();
|
||||
var jsonBody = JSON.stringify({
|
||||
sessionName = $("#sessionName").val(); // Video-call chosen by the user
|
||||
nickName = $("#participantName").val(); // Nickname chosen by the user
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'session': sessionName
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
|
||||
sessionId = response[0];
|
||||
token = response[1];
|
||||
sessionId = response[0]; // Get sessionId from response
|
||||
token = response[1]; // Get token from response
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
|
||||
callback();
|
||||
callback(); // Continue the join operation
|
||||
});
|
||||
}
|
||||
|
||||
function removeUser() {
|
||||
// Body of POST request with the name of the session and the token of the leaving user
|
||||
var jsonBody = JSON.stringify({
|
||||
'sessionName': sessionName,
|
||||
'token': token
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
|
||||
console.warn(userName + " correctly removed from session");
|
||||
});
|
||||
@ -195,7 +200,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
/* APPLICATION BACKEND METHODS */
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
|
||||
|
||||
|
||||
@ -60,15 +60,17 @@ var users = [{
|
||||
}];
|
||||
|
||||
|
||||
// Environment variables
|
||||
// Environment variable: URL where our OpenVidu server is listening
|
||||
var OPENVIDU_URL = process.argv[2];
|
||||
// Environment variable: secret shared with our OpenVidu server
|
||||
var OPENVIDU_SECRET = process.argv[3];
|
||||
|
||||
// OpenVidu object
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
|
||||
|
||||
// Objects for storing active sessions and users
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
var mapSessionNameSession = {};
|
||||
// Collection to pair sessionId's (identifiers of Session objects) and tokens
|
||||
var mapSessionIdTokens = {};
|
||||
|
||||
/* CONFIGURATION */
|
||||
@ -79,15 +81,20 @@ var mapSessionIdTokens = {};
|
||||
|
||||
// Login
|
||||
app.post('/api-login/login', function (req, res) {
|
||||
|
||||
// Retrieve params from POST body
|
||||
var user = req.body.user;
|
||||
var pass = req.body.pass;
|
||||
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
|
||||
|
||||
if (login(user, pass)) {
|
||||
if (login(user, pass)) { // Correct user-pass
|
||||
// Validate session and return OK
|
||||
// Value stored in req.session allows us to identify the user in future requests
|
||||
console.log("'" + user + "' has logged in");
|
||||
req.session.loggedUser = user;
|
||||
res.status(200).send();
|
||||
} else {
|
||||
} else { // Wrong user-pass
|
||||
// Invalidate session and return error
|
||||
console.log("'" + user + "' invalid credentials");
|
||||
req.session.destroy();
|
||||
res.status(401).send('User/Pass incorrect');
|
||||
@ -107,22 +114,40 @@ app.post('/api-sessions/get-sessionid-token', function (req, res) {
|
||||
req.session.destroy();
|
||||
res.status(401).send('User not logged');
|
||||
} else {
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
var sessionName = req.body.session;
|
||||
|
||||
// Role associated to this user
|
||||
var role = users.find(u => (u.user === req.session.loggedUser)).role;
|
||||
|
||||
// Optional data to be passed to other users when this user connects to the video-call
|
||||
// In this case, a JSON with the value we stored in the req.session object on login
|
||||
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
|
||||
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
var tokenOptions = new TokenOptions.Builder()
|
||||
.data(serverData)
|
||||
.role(role)
|
||||
.build();
|
||||
|
||||
if (mapSessionNameSession[sessionName]) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
console.log('Existing session ' + sessionName);
|
||||
|
||||
// Get the existing Session from the collection
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Get the existing sessionId
|
||||
var sessionId = mySession.getSessionId();
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
// Return the sessionId and token to the client
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
res.status(200).send({
|
||||
@ -130,17 +155,28 @@ app.post('/api-sessions/get-sessionid-token', function (req, res) {
|
||||
1: token
|
||||
});
|
||||
});
|
||||
} else {
|
||||
} else { // New session: return a new sessionId and a new token
|
||||
// Create a new OpenVidu Session
|
||||
console.log('New session ' + sessionName);
|
||||
var mySession = OV.createSession();
|
||||
|
||||
// Get the sessionId asynchronously
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessionNameSession[sessionName] = mySession;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionIdTokens[sessionId] = [];
|
||||
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
|
||||
// Return the sessionId and token to the client
|
||||
res.status(200).send({
|
||||
0: sessionId,
|
||||
1: token
|
||||
@ -157,16 +193,21 @@ app.post('/api-sessions/remove-user', function (req, res) {
|
||||
req.session.destroy();
|
||||
res.status(401).send('User not logged');
|
||||
} else {
|
||||
// Retrieve params from POST body
|
||||
var sessionName = req.body.sessionName;
|
||||
var token = req.body.token;
|
||||
console.log('Removing user | {sessionName, token}={' + sessionName + ", " + token + '}');
|
||||
|
||||
|
||||
// If the session exists ("TUTORIAL" in this case)
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
if (mySession) {
|
||||
var tokens = mapSessionIdTokens[mySession.getSessionId()];
|
||||
if (tokens) {
|
||||
var index = tokens.indexOf(token);
|
||||
if (index !== -1) { // User left the session
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed!
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + mapSessionIdTokens[mySession.getSessionId()].toString());
|
||||
} else {
|
||||
@ -174,7 +215,8 @@ app.post('/api-sessions/remove-user', function (req, res) {
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) { // Last user left the session
|
||||
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessionNameSession[sessionName];
|
||||
}
|
||||
|
||||
@ -49,20 +49,30 @@ public class LoginController {
|
||||
|
||||
@RequestMapping(value = "/dashboard", method = { RequestMethod.GET, RequestMethod.POST })
|
||||
public String login(@RequestParam(name = "user", required = false) String user,
|
||||
@RequestParam(name = "pass", required = false) String pass, Model model, HttpSession httpSession) {
|
||||
@RequestParam(name = "pass", required = false) String pass,
|
||||
Model model, HttpSession httpSession) {
|
||||
|
||||
// Check if the user is already logged in
|
||||
String userName = (String) httpSession.getAttribute("loggedUser");
|
||||
if (userName != null) { // User is already logged
|
||||
if (userName != null) {
|
||||
// User is already logged. Immediately return dashboard
|
||||
model.addAttribute("username", userName);
|
||||
return "dashboard";
|
||||
}
|
||||
System.out.println("Logging in | {user, pass}={" + user + ", " + pass + "}");
|
||||
if (login(user, pass)) { // User is logging in
|
||||
System.out.println("'" + user + "' has logged in");
|
||||
|
||||
// User wasn't logged and wants to
|
||||
if (login(user, pass)) { // Correct user-pass
|
||||
|
||||
// Validate session and return OK
|
||||
// Value stored in HttpSession allows us to identify the user in future requests
|
||||
httpSession.setAttribute("loggedUser", user);
|
||||
model.addAttribute("username", user);
|
||||
|
||||
// Return dashboard.html template
|
||||
return "dashboard";
|
||||
} else {
|
||||
|
||||
} else { // Wrong user-pass
|
||||
// Invalidate session and redirect to index.html
|
||||
httpSession.invalidate();
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
@ -20,12 +20,17 @@ import io.openvidu.java.client.TokenOptions;
|
||||
@Controller
|
||||
public class SessionController {
|
||||
|
||||
OpenVidu openVidu;
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
private OpenVidu openVidu;
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
|
||||
// Collection to pair sessionId's and tokens (the inner Map pairs tokens and role associated)
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
|
||||
|
||||
// URL where our OpenVidu server is listening
|
||||
private String OPENVIDU_URL;
|
||||
// Secret shared with our OpenVidu server
|
||||
private String SECRET;
|
||||
|
||||
public SessionController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
|
||||
@ -45,51 +50,74 @@ public class SessionController {
|
||||
}
|
||||
System.out.println("Getting sessionId and token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
// Role associated to this user
|
||||
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
|
||||
|
||||
// Optional data to be passed to other users when this user connects to the video-call
|
||||
// In this case, a JSON with the value we stored in the HttpSession object on login
|
||||
String serverData = "{\"serverData\": \"" + httpSession.getAttribute("loggedUser") + "\"}";
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
TokenOptions tokenOptions = new TokenOptions.Builder().data(serverData).role(role).build();
|
||||
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
System.out.println("Existing session " + sessionName);
|
||||
try {
|
||||
|
||||
// Get the existing sessionId from our collection with
|
||||
// the sessionName param ("TUTORIAL")
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
|
||||
|
||||
// Update our collection storing the new token
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
|
||||
// Add all the needed attributes to the template
|
||||
model.addAttribute("sessionId", sessionId);
|
||||
model.addAttribute("token", token);
|
||||
model.addAttribute("nickName", clientData);
|
||||
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
|
||||
model.addAttribute("sessionName", sessionName);
|
||||
|
||||
// Return session.html template
|
||||
return "session";
|
||||
|
||||
} catch (Exception e) {
|
||||
// If error just return dashboard.html template
|
||||
model.addAttribute("username", httpSession.getAttribute("loggedUser"));
|
||||
return "dashboard";
|
||||
}
|
||||
|
||||
} else {
|
||||
// New session: return a new sessionId and token
|
||||
// New session: return a new sessionId and a new token
|
||||
System.out.println("New session " + sessionName);
|
||||
try {
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
Session session = this.openVidu.createSession();
|
||||
// Get the sessionId
|
||||
String sessionId = session.getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = session.generateToken(tokenOptions);
|
||||
|
||||
// Store the session and the token in our collections
|
||||
this.mapSessions.put(sessionName, session);
|
||||
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
|
||||
// Add all the needed attributes to the template
|
||||
model.addAttribute("sessionId", sessionId);
|
||||
model.addAttribute("token", token);
|
||||
model.addAttribute("nickName", clientData);
|
||||
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
|
||||
model.addAttribute("sessionName", sessionName);
|
||||
|
||||
// Return session.html template
|
||||
return "session";
|
||||
|
||||
} catch (Exception e) {
|
||||
// If error just return dashboard.html template
|
||||
model.addAttribute("username", httpSession.getAttribute("loggedUser"));
|
||||
return "dashboard";
|
||||
}
|
||||
@ -107,29 +135,33 @@ public class SessionController {
|
||||
}
|
||||
System.out.println("Removing user | sessioName=" + sessionName + ", token=" + token);
|
||||
|
||||
// If the session exists
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
|
||||
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
|
||||
// If the token exists
|
||||
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
|
||||
System.out.println(sessionName + ": " + this.mapSessionIdsTokens.get(sessionId).toString());
|
||||
// User left the session
|
||||
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
|
||||
// Last user left the session
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
System.out.println(sessionName + " empty!");
|
||||
}
|
||||
model.addAttribute("sessionId", sessionId);
|
||||
return "redirect:/dashboard";
|
||||
} else {
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return "redirect:/dashboard";
|
||||
}
|
||||
} else {
|
||||
// The SESSIONID wasn't valid
|
||||
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
|
||||
return "redirect:/dashboard";
|
||||
}
|
||||
} else {
|
||||
// The SESSION does not exist
|
||||
System.out.println("Problems in the app server: the SESSION does not exist");
|
||||
return "redirect:/dashboard";
|
||||
}
|
||||
|
||||
@ -44,10 +44,12 @@
|
||||
<div id="img-div"><img src="images/openvidu_grey_bg_transp_cropped.png" /></div>
|
||||
<form class="form-group jumbotron" action="/dashboard" method="post">
|
||||
<p>
|
||||
<label>User</label><input class="form-control" type="text" name="user" required="true"></input>
|
||||
<label>User</label>
|
||||
<input class="form-control" type="text" name="user" required="true"></input>
|
||||
</p>
|
||||
<p>
|
||||
<label>Pass</label><input class="form-control" type="password" name="pass" required="true"></input>
|
||||
<label>Pass</label>
|
||||
<input class="form-control" type="password" name="pass" required="true"></input>
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<button class="btn btn-lg btn-info" type="submit">Log in</button>
|
||||
|
||||
@ -136,7 +136,7 @@
|
||||
};
|
||||
initMainVideo(event.element, userData);
|
||||
appendUserData(event.element, userData);
|
||||
$(event.element).prop('muted', true);
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -60,15 +60,17 @@ var users = [{
|
||||
role: OpenViduRole.SUBSCRIBER
|
||||
}];
|
||||
|
||||
// Environment variables
|
||||
// Environment variable: URL where our OpenVidu server is listening
|
||||
var OPENVIDU_URL = process.argv[2];
|
||||
// Environment variable: secret shared with our OpenVidu server
|
||||
var OPENVIDU_SECRET = process.argv[3];
|
||||
|
||||
// OpenVidu object
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
|
||||
|
||||
// Objects for storing active sessions and users
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
var mapSessionNameSession = {};
|
||||
// Collection to pair sessionId's (identifiers of Session objects) and tokens
|
||||
var mapSessionIdTokens = {};
|
||||
|
||||
/* CONFIGURATION */
|
||||
@ -100,28 +102,36 @@ app.get('/dashboard', dashboardController);
|
||||
|
||||
function dashboardController(req, res) {
|
||||
|
||||
if (isLogged(req.session)) {
|
||||
user = req.session.loggedUser;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else {
|
||||
var user = req.body.user;
|
||||
// Check if the user is already logged in
|
||||
if (isLogged(req.session)) {
|
||||
// User is already logged. Immediately return dashboard
|
||||
user = req.session.loggedUser;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else {
|
||||
// User wasn't logged and wants to
|
||||
|
||||
// Retrieve params from POST body
|
||||
var user = req.body.user;
|
||||
var pass = req.body.pass;
|
||||
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
|
||||
|
||||
if (login(user, pass)) {
|
||||
|
||||
if (login(user, pass)) { // Correct user-pass
|
||||
// Validate session and return OK
|
||||
// Value stored in req.session allows us to identify the user in future requests
|
||||
console.log("'" + user + "' has logged in");
|
||||
req.session.loggedUser = user;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else {
|
||||
req.session.loggedUser = user;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else { // Wrong user-pass
|
||||
// Invalidate session and return index template
|
||||
console.log("'" + user + "' invalid credentials");
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
}
|
||||
}
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.post('/session', (req, res) => {
|
||||
@ -129,23 +139,43 @@ app.post('/session', (req, res) => {
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
} else {
|
||||
// The nickname sent by the client
|
||||
var clientData = req.body.data;
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
var sessionName = req.body.sessionname;
|
||||
|
||||
// Role associated to this user
|
||||
var role = users.find(u => (u.user === req.session.loggedUser)).role;
|
||||
|
||||
// Optional data to be passed to other users when this user connects to the video-call
|
||||
// In this case, a JSON with the value we stored in the req.session object on login
|
||||
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
|
||||
|
||||
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
var tokenOptions = new TokenOptions.Builder()
|
||||
.data(serverData)
|
||||
.role(role)
|
||||
.build();
|
||||
|
||||
if (mapSessionNameSession[sessionName]) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
console.log('Existing session ' + sessionName);
|
||||
|
||||
// Get the existing Session from the collection
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Get the existing sessionId
|
||||
var sessionId = mySession.getSessionId();
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
// Return session template with all the needed attributes
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
res.render('session.ejs', {
|
||||
@ -156,15 +186,27 @@ app.post('/session', (req, res) => {
|
||||
sessionName: sessionName
|
||||
});
|
||||
});
|
||||
} else {
|
||||
} else { // New session: return a new sessionId and a new token
|
||||
console.log('New session ' + sessionName);
|
||||
var mySession = OV.createSession();
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
mapSessionNameSession[sessionName] = mySession;
|
||||
mapSessionIdTokens[sessionId] = [];
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
var mySession = OV.createSession();
|
||||
|
||||
// Get the sessionId asynchronously
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessionNameSession[sessionName] = mySession;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionIdTokens[sessionId] = [];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
// Return session template with all the needed attributes
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
res.render('session.ejs', {
|
||||
@ -185,16 +227,21 @@ app.post('/leave-session', (req, res) => {
|
||||
req.session.destroy();
|
||||
res.render('index.ejs');
|
||||
} else {
|
||||
// Retrieve params from POST body
|
||||
var sessionName = req.body.sessionname;
|
||||
var token = req.body.token;
|
||||
console.log('Removing user | {sessionName, token}={' + sessionName + ', ' + token + '}');
|
||||
|
||||
|
||||
// If the session exists
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
if (mySession) {
|
||||
var tokens = mapSessionIdTokens[mySession.getSessionId()];
|
||||
if (tokens) {
|
||||
var index = tokens.indexOf(token);
|
||||
if (index !== -1) { // User left the session
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed!
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + mapSessionIdTokens[mySession.getSessionId()].toString());
|
||||
} else {
|
||||
@ -202,7 +249,8 @@ app.post('/leave-session', (req, res) => {
|
||||
console.log(msg);
|
||||
res.redirect('/dashboard');
|
||||
}
|
||||
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) { // Last user left the session
|
||||
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessionNameSession[sessionName];
|
||||
}
|
||||
|
||||
@ -44,10 +44,12 @@
|
||||
<div id="img-div"><img src="images/openvidu_grey_bg_transp_cropped.png" /></div>
|
||||
<form class="form-group jumbotron" action="/dashboard" method="post">
|
||||
<p>
|
||||
<label>User</label><input class="form-control" type="text" name="user" required="true"></input>
|
||||
<label>User</label>
|
||||
<input class="form-control" type="text" name="user" required="true"></input>
|
||||
</p>
|
||||
<p>
|
||||
<label>Pass</label><input class="form-control" type="password" name="pass" required="true"></input>
|
||||
<label>Pass</label>
|
||||
<input class="form-control" type="password" name="pass" required="true"></input>
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<button class="btn btn-lg btn-info" type="submit">Log in</button>
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
// Add a new HTML element for the user's name and nickname just below its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
});
|
||||
});
|
||||
@ -106,6 +106,7 @@
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
@ -118,7 +119,7 @@
|
||||
if (isPublisher()) {
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true,
|
||||
video: true,
|
||||
@ -134,12 +135,12 @@
|
||||
};
|
||||
initMainVideo(event.element, userData);
|
||||
appendUserData(event.element, userData);
|
||||
$(event.element).prop('muted', true);
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user