From 23f2df11d587306469bd4aa51e8d1f4eaab89119 Mon Sep 17 00:00:00 2001
From: Anton Georgiev <anto.georgiev@gmail.com>
Date: Wed, 18 Nov 2020 20:31:36 +0000
Subject: [PATCH] code changes to allow for meetings' redis events to be
 processed on different html5 nodejs pids

---
 .../imports/startup/client/intl.jsx           |  2 +-
 .../imports/startup/server/redis.js           | 38 +++++++++++++++----
 .../ui/components/legacy/component.jsx        |  2 +-
 .../ui/components/meeting-ended/component.jsx |  2 +-
 .../imports/ui/components/settings/service.js |  2 +-
 .../grails-app/conf/bigbluebutton.properties  |  2 +-
 .../web/controllers/ApiController.groovy      |  5 +++
 7 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/bigbluebutton-html5/imports/startup/client/intl.jsx b/bigbluebutton-html5/imports/startup/client/intl.jsx
index 88f6292deb..741b9c0f59 100644
--- a/bigbluebutton-html5/imports/startup/client/intl.jsx
+++ b/bigbluebutton-html5/imports/startup/client/intl.jsx
@@ -92,7 +92,7 @@ class IntlStartup extends Component {
   }
 
   fetchLocalizedMessages(locale, init = false) {
-    const url = `/html5client/locale?locale=${locale}&init=${init}`;
+    const url = `./locale?locale=${locale}&init=${init}`;
 
     this.setState({ fetching: true }, () => {
       fetch(url)
diff --git a/bigbluebutton-html5/imports/startup/server/redis.js b/bigbluebutton-html5/imports/startup/server/redis.js
index 739164c47d..cb6b403a5d 100755
--- a/bigbluebutton-html5/imports/startup/server/redis.js
+++ b/bigbluebutton-html5/imports/startup/server/redis.js
@@ -108,6 +108,9 @@ class RedisPubSub {
     this.didSendRequestEvent = false;
     const host = process.env.REDIS_HOST || Meteor.settings.private.redis.host;
     const redisConf = Meteor.settings.private.redis;
+    this.instanceMax = parseInt(process.env.INSTANCE_MAX || "1");
+    this.instanceId = process.env.INSTANCE_ID || "1";
+
     const { password, port } = redisConf;
 
     if (password) {
@@ -122,6 +125,7 @@ class RedisPubSub {
 
     this.emitter = new EventEmitter2();
     this.mettingsQueues = {};
+    this.mettingsQueues[NO_MEETING_ID] = new MeetingMessageQueue(this.emitter, this.config.async, this.config.debug);
 
     this.handleSubscribe = this.handleSubscribe.bind(this);
     this.handleMessage = this.handleMessage.bind(this);
@@ -180,16 +184,33 @@ class RedisPubSub {
 
     const queueId = meetingId || NO_MEETING_ID;
 
-    if (!(queueId in this.mettingsQueues)) {
-      this.mettingsQueues[meetingId] = new MeetingMessageQueue(this.emitter, async, this.debug);
+    if (eventName === 'MeetingCreatedEvtMsg'){
+      const newIntId = parsedMessage.core.body.props.meetingProp.intId;
+      const metadata = parsedMessage.core.body.props.metadataProp.metadata;
+      const instanceId = metadata['bbb-meetinginstance'];
+
+      Logger.info("MeetingCreatedEvtMsg received with meetingInstance: " + instanceId + " -- this is instance: " + this.instanceId);
+
+      if (instanceId === this.instanceId){
+        this.mettingsQueues[newIntId] = new MeetingMessageQueue(this.emitter, async, this.debug);
+      } else {
+        // Logger.error('THIS NODEJS IS **NOT** PROCESSING EVENTS FOR THIS MEETING')
+      }
     }
 
-    this.mettingsQueues[meetingId].add({
-      pattern,
-      channel,
-      eventName,
-      parsedMessage,
-    });
+    if (queueId in this.mettingsQueues) {
+      this.mettingsQueues[queueId].add({
+        pattern,
+        channel,
+        eventName,
+        parsedMessage,
+      });
+    }
+    //else {
+    //Logger.info("Skipping redis message for " + queueId);
+    //}
+
+
   }
 
   destroyMeetingQueue(id) {
@@ -258,3 +279,4 @@ Meteor.startup(() => {
 });
 
 export default RedisPubSubSingleton;
+
diff --git a/bigbluebutton-html5/imports/ui/components/legacy/component.jsx b/bigbluebutton-html5/imports/ui/components/legacy/component.jsx
index 1fdb38a717..f6c049f345 100755
--- a/bigbluebutton-html5/imports/ui/components/legacy/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/legacy/component.jsx
@@ -78,7 +78,7 @@ export default class Legacy extends Component {
       || navigator.language
       || Meteor.settings.public.app.defaultSettings.application.fallbackLocale;
 
-    const url = `/html5client/locale?locale=${locale}`;
+    const url = `./locale?locale=${locale}`;
 
     const that = this;
     this.state = { viewState: FETCHING };
diff --git a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
index 6953534276..819fa865ca 100755
--- a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
@@ -159,7 +159,7 @@ class MeetingEnded extends PureComponent {
       comment: MeetingEnded.getComment(),
       userRole: this.localUserRole,
     };
-    const url = '/html5client/feedback';
+    const url = './feedback';
     const options = {
       method: 'POST',
       body: JSON.stringify(message),
diff --git a/bigbluebutton-html5/imports/ui/components/settings/service.js b/bigbluebutton-html5/imports/ui/components/settings/service.js
index 9d894d8c7a..85af45dddd 100644
--- a/bigbluebutton-html5/imports/ui/components/settings/service.js
+++ b/bigbluebutton-html5/imports/ui/components/settings/service.js
@@ -27,7 +27,7 @@ const updateSettings = (obj, msg) => {
   }
 };
 
-const getAvailableLocales = () => fetch('/html5client/locales').then(locales => locales.json());
+const getAvailableLocales = () => fetch('./locales').then(locales => locales.json());
 
 export {
   getUserRoles,
diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties
index 4b748b9683..7f175be89e 100755
--- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties
+++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties
@@ -258,7 +258,7 @@ moderatorsJoinViaHTML5Client=true
 
 # The url of the BigBlueButton HTML5 client. Users will be redirected here when
 # successfully joining the meeting.
-html5ClientUrl=${bigbluebutton.web.serverURL}/html5client/join
+html5ClientUrl=${bigbluebutton.web.serverURL}/html5client/%%INSTANCEID%%/join
 
 
 # The url for where the guest will poll if approved to join or not.
diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
index 9972fcbbe6..22792a98d7 100755
--- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
+++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
@@ -510,6 +510,11 @@ class ApiController {
       }
     }
 
+
+    String meetingInstance = meeting.getMetadata()["bbb-meetinginstance"];
+    meetingInstance = (meetingInstance == null) ? "1" : meetingInstance;
+    clientURL = clientURL.replaceAll("%%INSTANCEID%%", meetingInstance);
+
     if (!StringUtils.isEmpty(params.redirect)) {
       try {
         redirectClient = Boolean.parseBoolean(params.redirect);
-- 
GitLab