HTML5 client access to Redis

300 views
Skip to first unread message

Brent W. Baccala

unread,
Sep 20, 2020, 11:47:46 PM9/20/20
to BigBlueButton-dev
According to the "Internal network connections" diagram on the architecture page, the HTML 5 client has a direct connection to Redis.

However, I can't find anything in the client code that connects to Redis.  I've tried grep'ing for things like 'redi' and 'import', and just can't find anything except server connections.

I do need to make a call to akka-bbb-apps from a client.  Do I need to go through Meteor to do this?  I.e, send a message to the Meteor server to post something to Redis and then relay the answer back through Meteor, or does the client have a direct connection to Redis?

The more I think about it, the more I think the diagram must be wrong.  I don't have anything in my network ACL to allow the client to make connections to Redis, and I don't see anything in the nginx configuration to relay connections to Redis.

Anybody know for sure?

    agape
    brent

Message has been deleted

pierre...@gmail.com

unread,
Sep 28, 2020, 1:16:26 PM9/28/20
to BigBlueButton-dev
Hello,

its really an excellent question with a great answer that explains how it works.

I am using greenlight with bbb, and I want to send some info from MongoDB or Redis to the postgresDB, do you know how it works?

Thank you in advance for your answer,

Best regards !
Le jeudi 24 septembre 2020 à 04:21:13 UTC-4, bilob...@gmail.com a écrit :
Hi Brent,
-  I think in order to send msgs (referred to as payload) to redis , you'll have to use 
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
- The event name must have a handler on the akka-bbb-apps side in order to relay the messages to other users. 
- As for CLIENT --> REDIS direct connection there are security concerns around this approach, beside the server is already authenticated to redis , why add Client auth as well.
(take a look at '/imports/startup/server/redis') to see how authentication is done
regards
--
You received this message because you are subscribed to the Google Groups "BigBlueButton-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bigbluebutton-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bigbluebutton-dev/beff41a2-78cc-48a2-ac06-a4d6504b8f6en%40googlegroups.com.

Ange Toko

unread,
Feb 10, 2021, 10:33:00 AM2/10/21
to BigBlueButton-dev
Hi all i am having almost the same issue sending a message payload to akka-bbb-apps. I am working on a project to integrate a 3d scene in a bbb-meeting. I am using babylon js to render my 3d Scene on the client. The scene gets published locally, when a user presses a "3d start" button, the presentation slides swaps down and the scene is sent as a blob uri in a json object to the server api using the Meteor.method "insert". After digging in this group i realized that to publish the scene on all clients, i had to send my json object as a payload over RedisPubSub to akka-bbb-app passing through bbb-common-message. But after doing all of these it still doesn't work and on pressing the button, the scene is still just published locally (although the blob gets added in minimongo) and i get the following error from akka-bbb-apps.

Scala, meteor and ddp is all new to me so every help would be appreciated.
PS: The scene is being sent from the client-side, where i render it in the browser with react

---------------------------------------------------------------------------------------------------------------------------------------
2021-02-10T09:12:44.850-05:00 ERROR o.b.c.p.s.ReceivedJsonMsgHandlerActor - Failed to deserialize message Missing creator property 'scenes' (index 0); `DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES` enabled
 at [Source: (String)"{"header":{"name":"AddScenePubMsg","meetingId":"183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1612966186260","userId":"w_teqwsfd1nrjg"},"body":{"doc":{"doc":"blob:https://ange.mywire.org/c2a04238-bb2a-4bc7-a640-00ec4eb6c41a"}}}"; line: 1, column: 221] (through reference chain: org.bigbluebutton.common2.msgs.AddScenePubMsg["body"])
----------------------------------------------------------------------------------------------------------------------------------------

The code is as follows:
I added my  ""AddScenePubMsg" to bbb-common-message as shown bellow:

`````
package org.bigbluebutton.common2.msgs

import org.bigbluebutton.common2.domain.SceneVO

object AddScenePubMsg { val NAME = "AddScenePubMsg" }
case class AddScenePubMsg(header: BbbClientMsgHeader, body: AddScenePubMsgBody) extends StandardMsg
case class AddScenePubMsgBody(scenes: SceneVO)

``````
Then in akka-bbb-apps  i added the handler "AddScenePubMsg" and a ThreeDimensionApp and Model. The Code for AddScenePubMsgHlr.scala is as follows

```
package org.bigbluebutton.core.apps.threedimension

import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ThreeDimension
import org.bigbluebutton.common2.domain.SceneVO
import org.bigbluebutton.core.bus.MessageBus
import org.bigbluebutton.core.running.{ LiveMeeting }

trait AddScenePubMsgHdlr {
this: ThreeDimensionApp2x =>

def handle(msg: AddScenePubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
val scens = new collection.mutable.HashMap[String, ThreeDimension]

def broadcastEvent(msg: AddScenePubMsg, userId: String, scene: SceneVO, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, userId)
val envelope = BbbCoreEnvelope(AddScenePubMsg.NAME, routing)
val header = BbbClientMsgHeader(AddScenePubMsg.NAME, liveMeeting.props.meetingProp.intId, userId)

val body = AddScenePubMsgBody(scene)
val event = AddScenePubMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
bus.outGW.send(msgEvent)
}
processPreuploadedScenes(liveMeeting, scens.values.toVector)

broadcastEvent(msg, msg.header.userId, msg.body.scenes, liveMeeting, bus)

}

}
```
The Code for ThreeDimensionApp is as follows

```
package org.bigbluebutton.core.apps.threedimension

import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.core.apps.ThreeDimension
import org.bigbluebutton.core.running.LiveMeeting

class ThreeDimensionApp2x(implicit val context: ActorContext)
extends AddScenePubMsgHdlr {

val log = Logging(context.system, getClass)
def processPreuploadedScenes(liveMeeting: LiveMeeting, scenes: Vector[ThreeDimension]) {
scenes.foreach(scene => {
liveMeeting.threedModel.addScene(scene)
})

liveMeeting.threedModel.getCurrentScene(scenes.head.docId) match {
case Some(s) => // do nothing
case None => setCurrentScene(liveMeeting, scenes.head.docId)
}
}

def setCurrentScene(liveMeeting: LiveMeeting, sceneId: String): Option[ThreeDimension] = {
liveMeeting.threedModel.setCurrentScene(sceneId)
}

def getSceneInfo(liveMeeting: LiveMeeting): Vector[ThreeDimension] = {
liveMeeting.threedModel.getScenes
}
}
````
And the code for ThreeDimensionModel is as follows:

````
package org.bigbluebutton.core.apps


case class ThreeDimension(docId: String, doc String)

class ThreeDimensionModel {
private var scenes = new scala.collection.immutable.HashMap[String, ThreeDimension]

def addScene(sce: ThreeDimension) { // todo remove
scenes += sce.docId -> sce
}
def getScenes(): Vector[ThreeDimension] = { // todo remove
scenes.values.toVector
}
def getCurrentScene(sceneId: String): Option[ThreeDimension] = { // todo remove
scenes.values find (p => p.docId == sceneId)

}
def setCurrentScene(sceneId: String): Option[ThreeDimension] = { // todo remove
getScenes().foreach(curScene => {
if (curScene.docId != sceneId) {
addScene(curScene)
}
})

scenes.get(sceneId) match {
case Some(scene) =>
addScene(scene)
Some(scene)
case None => None
}
}
````
Le jeudi 24 septembre 2020 à 04:21:13 UTC-4, bilob...@gmail.com a écrit :
Hi Brent,
-  I think in order to send msgs (referred to as payload) to redis , you'll have to use 
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
- The event name must have a handler on the akka-bbb-apps side in order to relay the messages to other users. 
- As for CLIENT --> REDIS direct connection there are security concerns around this approach, beside the server is already authenticated to redis , why add Client auth as well.
(take a look at '/imports/startup/server/redis') to see how authentication is done
regards

On Mon, Sep 21, 2020 at 4:47 AM Brent W. Baccala <cos...@freesoft.org> wrote:

Brent W. Baccala

unread,
Feb 10, 2021, 5:00:55 PM2/10/21
to BigBlueButton-dev
Dear Ange -

Your work on Babylon is quite similar to what I've done with a remote desktop.  In fact, my system could probably do some of what you want - I've certainly run Babylon in a remote web browser.

You probably don't need to modify akka-bbb-apps.

If you clone my github bbb repository (BrentBaccala/bigbluebutton), and run this diff:
    git diff 5b3a41^^^^ 5b3a41
you'll see the basic changes I had to make to get remote desktop working.  That diff is from August of last year, so a lot has changed since then, but that's the basic code.

Highlights:
  • All I send to the clients is a URL that they use to connect to the remote desktop.  You may or may not want to use this approach yourself: send them a URL to download the Babylon JSON themselves.
  • The getRemoteDesktopUrl function is how the clients get the URL.  They query a database to see if a field named remoteDesktopUrl is present.  We rely on the React/Meteor library to automatically re-run this code when the database changes.  It's just this:
const getRemoteDesktopUrl = () => {
  const meetingId = Auth.meetingID;
  const meeting = Meetings.findOne({ meetingId }, { fields: { remoteDesktopUrl: 1 } });

  return meeting && meeting.remoteDesktopUrl;
};
  • Meetings is an existing shared Mongo database.  It's declared in /imports/api/meetings
  • startWatching is how a client shares a desktop.  It just makes an RPC call from the Meteor client to Meteor server:
const startWatching = (remoteDesktopUrl) => {
  makeCall('startWatchingRemoteDesktop', { remoteDesktopUrl });
};
  • The function has to be declared as an RPC.  That happens here:
Meteor.methods({
  startWatchingRemoteDesktop,
  stopWatchingRemoteDesktop,
});
  • startWatchingRemoteDesktop is what announces the URL to all of the clients.  It runs on the Meteor server.  The redis stuff here is extraneous.  All that's really needed is to update Meetings.  Here it is:
export default function startWatchingRemoteDesktop(options) {
  const REDIS_CONFIG = Meteor.settings.private.redis;
  const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
  const EVENT_NAME = 'StartRemoteDesktopMsg';

  const { meetingId, requesterUserId } = extractCredentials(this.userId);
  const { remoteDesktopUrl } = options;

  check(remoteDesktopUrl, String);

  Meetings.update({ meetingId }, { $set: { remoteDesktopUrl } });

  const payload = { remoteDesktopUrl };

  Logger.info(`User id=${requesterUserId} sharing a remote desktop: ${remoteDesktopUrl} for meeting ${meetingId}`);

  return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
}
  • Now that I think about it, the RPC might be unnecessary.  It might be possible for the client to update Meetings directly, but I'm not sure.  I know this stuff better now than I did in August, but lots of it is still a mystery.
Also, commit 065900 is when I first added full screen functionality, which is probably something you'll eventually want.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages