Merge pull request #20132 from antobinary/html5-pack-30
refactor/build: drop html5InstanceId and simplify bbb-html5 frontend/backend
This commit is contained in:
commit
628c3bb32b
4
.github/workflows/automated-tests.yml
vendored
4
.github/workflows/automated-tests.yml
vendored
@ -256,6 +256,9 @@ jobs:
|
|||||||
'
|
'
|
||||||
- name: Install BBB
|
- name: Install BBB
|
||||||
uses: nick-fields/retry@v3
|
uses: nick-fields/retry@v3
|
||||||
|
env:
|
||||||
|
NODE_EXTRA_CA_CERTS: /usr/local/share/ca-certificates/bbb-dev/bbb-dev-ca.crt
|
||||||
|
ACTIONS_RUNNER_DEBUG: true
|
||||||
with:
|
with:
|
||||||
timeout_minutes: 25
|
timeout_minutes: 25
|
||||||
max_attempts: 2
|
max_attempts: 2
|
||||||
@ -265,7 +268,6 @@ jobs:
|
|||||||
cd /root/ && wget -nv https://raw.githubusercontent.com/bigbluebutton/bbb-install/v3.0.x-release/bbb-install.sh -O bbb-install.sh
|
cd /root/ && wget -nv https://raw.githubusercontent.com/bigbluebutton/bbb-install/v3.0.x-release/bbb-install.sh -O bbb-install.sh
|
||||||
cat bbb-install.sh | sed "s|> /etc/apt/sources.list.d/bigbluebutton.list||g" | bash -s -- -v jammy-30-dev -s bbb-ci.test -j -d /certs/
|
cat bbb-install.sh | sed "s|> /etc/apt/sources.list.d/bigbluebutton.list||g" | bash -s -- -v jammy-30-dev -s bbb-ci.test -j -d /certs/
|
||||||
bbb-conf --salt bbbci
|
bbb-conf --salt bbbci
|
||||||
echo "NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/bbb-dev/bbb-dev-ca.crt" >> /usr/share/meteor/bundle/bbb-html5-with-roles.conf
|
|
||||||
sed -i "s/\"minify\": true,/\"minify\": false,/" /usr/share/etherpad-lite/settings.json
|
sed -i "s/\"minify\": true,/\"minify\": false,/" /usr/share/etherpad-lite/settings.json
|
||||||
bbb-conf --restart
|
bbb-conf --restart
|
||||||
EOF
|
EOF
|
||||||
|
@ -154,7 +154,7 @@ class BigBlueButtonActor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def handleGetAllMeetingsReqMsg(msg: GetAllMeetingsReqMsg): Unit = {
|
private def handleGetAllMeetingsReqMsg(msg: GetAllMeetingsReqMsg): Unit = {
|
||||||
RunningMeetings.meetings(meetings).filter(_.props.systemProps.html5InstanceId == msg.body.html5InstanceId).foreach(m => {
|
RunningMeetings.meetings(meetings).foreach(m => {
|
||||||
m.actorRef ! msg
|
m.actorRef ! msg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ trait SyncGetGroupChatsInfoMsgHdlr {
|
|||||||
def handleSyncGetGroupChatsInfo(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = {
|
def handleSyncGetGroupChatsInfo(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = {
|
||||||
|
|
||||||
def buildSyncGetGroupChatsRespMsg(allChats: Vector[GroupChatInfo]): BbbCommonEnvCoreMsg = {
|
def buildSyncGetGroupChatsRespMsg(allChats: Vector[GroupChatInfo]): BbbCommonEnvCoreMsg = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val envelope = BbbCoreEnvelope(SyncGetGroupChatsRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetGroupChatsRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SyncGetGroupChatsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
val header = BbbClientMsgHeader(SyncGetGroupChatsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val body = SyncGetGroupChatsRespMsgBody(allChats)
|
val body = SyncGetGroupChatsRespMsgBody(allChats)
|
||||||
@ -21,7 +21,7 @@ trait SyncGetGroupChatsInfoMsgHdlr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def buildSyncGetGroupChatMsgsRespMsg(msgs: Vector[GroupChatMsgToUser], chatId: String): BbbCommonEnvCoreMsg = {
|
def buildSyncGetGroupChatMsgsRespMsg(msgs: Vector[GroupChatMsgToUser], chatId: String): BbbCommonEnvCoreMsg = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val envelope = BbbCoreEnvelope(SyncGetGroupChatMsgsRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetGroupChatMsgsRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SyncGetGroupChatMsgsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
val header = BbbClientMsgHeader(SyncGetGroupChatMsgsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val body = SyncGetGroupChatMsgsRespMsgBody(chatId, msgs)
|
val body = SyncGetGroupChatMsgsRespMsgBody(chatId, msgs)
|
||||||
|
@ -9,7 +9,7 @@ trait SyncGetMeetingInfoRespMsgHdlr {
|
|||||||
val outGW: OutMsgRouter
|
val outGW: OutMsgRouter
|
||||||
|
|
||||||
def handleSyncGetMeetingInfoRespMsg(props: DefaultProps): Unit = {
|
def handleSyncGetMeetingInfoRespMsg(props: DefaultProps): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(props.meetingProp.intId, props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, props.meetingProp.intId, "nodeJSapp")
|
||||||
val envelope = BbbCoreEnvelope(SyncGetMeetingInfoRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetMeetingInfoRespMsg.NAME, routing)
|
||||||
val header = BbbCoreBaseHeader(SyncGetMeetingInfoRespMsg.NAME)
|
val header = BbbCoreBaseHeader(SyncGetMeetingInfoRespMsg.NAME)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ trait SyncGetPresentationPodsMsgHdlr {
|
|||||||
def handleSyncGetPresentationPods(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = {
|
def handleSyncGetPresentationPods(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = {
|
||||||
|
|
||||||
def buildSyncGetPresentationPodsRespMsg(pods: Vector[PresentationPodVO]): BbbCommonEnvCoreMsg = {
|
def buildSyncGetPresentationPodsRespMsg(pods: Vector[PresentationPodVO]): BbbCommonEnvCoreMsg = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val envelope = BbbCoreEnvelope(SyncGetPresentationPodsRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetPresentationPodsRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SyncGetPresentationPodsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
val header = BbbClientMsgHeader(SyncGetPresentationPodsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
|
|
||||||
|
@ -9,9 +9,10 @@ trait SyncGetScreenshareInfoRespMsgHdlr {
|
|||||||
this: ScreenshareApp2x =>
|
this: ScreenshareApp2x =>
|
||||||
|
|
||||||
def handleSyncGetScreenshareInfoRespMsg(liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handleSyncGetScreenshareInfoRespMsg(liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(
|
val routing = Routing.addMsgToClientRouting(
|
||||||
|
MessageTypes.BROADCAST_TO_MEETING,
|
||||||
liveMeeting.props.meetingProp.intId,
|
liveMeeting.props.meetingProp.intId,
|
||||||
liveMeeting.props.systemProps.html5InstanceId.toString
|
"nodeJSapp"
|
||||||
)
|
)
|
||||||
val envelope = BbbCoreEnvelope(SyncGetScreenshareInfoRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetScreenshareInfoRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(
|
val header = BbbClientMsgHeader(
|
||||||
|
@ -11,7 +11,7 @@ trait SyncGetUsersMeetingRespMsgHdlr {
|
|||||||
val outGW: OutMsgRouter
|
val outGW: OutMsgRouter
|
||||||
|
|
||||||
def handleSyncGetUsersMeetingRespMsg(): Unit = {
|
def handleSyncGetUsersMeetingRespMsg(): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val envelope = BbbCoreEnvelope(SyncGetUsersMeetingRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetUsersMeetingRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SyncGetUsersMeetingRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
val header = BbbClientMsgHeader(SyncGetUsersMeetingRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ trait SyncGetVoiceUsersMsgHdlr {
|
|||||||
callerNum = u.callerNum, color = u.color, muted = u.muted, talking = u.talking, listenOnly = u.listenOnly)
|
callerNum = u.callerNum, color = u.color, muted = u.muted, talking = u.talking, listenOnly = u.listenOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val envelope = BbbCoreEnvelope(SyncGetVoiceUsersRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetVoiceUsersRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SyncGetVoiceUsersRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
val header = BbbClientMsgHeader(SyncGetVoiceUsersRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp")
|
||||||
val body = SyncGetVoiceUsersRespMsgBody(voiceUsers)
|
val body = SyncGetVoiceUsersRespMsgBody(voiceUsers)
|
||||||
|
@ -13,9 +13,10 @@ trait SyncGetWebcamInfoRespMsgHdlr {
|
|||||||
this: WebcamApp2x =>
|
this: WebcamApp2x =>
|
||||||
|
|
||||||
def handleSyncGetWebcamInfoRespMsg(liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handleSyncGetWebcamInfoRespMsg(liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(
|
val routing = Routing.addMsgToClientRouting(
|
||||||
|
MessageTypes.BROADCAST_TO_MEETING,
|
||||||
liveMeeting.props.meetingProp.intId,
|
liveMeeting.props.meetingProp.intId,
|
||||||
liveMeeting.props.systemProps.html5InstanceId.toString
|
"nodeJSapp"
|
||||||
)
|
)
|
||||||
val envelope = BbbCoreEnvelope(SyncGetWebcamInfoRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SyncGetWebcamInfoRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(
|
val header = BbbClientMsgHeader(
|
||||||
|
@ -11,7 +11,7 @@ trait ClearWhiteboardPubMsgHdlr extends RightsManagementTrait {
|
|||||||
def handle(msg: ClearWhiteboardPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handle(msg: ClearWhiteboardPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(msg: ClearWhiteboardPubMsg, fullClear: Boolean): Unit = {
|
def broadcastEvent(msg: ClearWhiteboardPubMsg, fullClear: Boolean): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
val envelope = BbbCoreEnvelope(ClearWhiteboardEvtMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(ClearWhiteboardEvtMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(ClearWhiteboardEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
val header = BbbClientMsgHeader(ClearWhiteboardEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ trait DeleteWhiteboardAnnotationsPubMsgHdlr extends RightsManagementTrait {
|
|||||||
def handle(msg: DeleteWhiteboardAnnotationsPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handle(msg: DeleteWhiteboardAnnotationsPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(msg: DeleteWhiteboardAnnotationsPubMsg, removedAnnotationsIds: Array[String]): Unit = {
|
def broadcastEvent(msg: DeleteWhiteboardAnnotationsPubMsg, removedAnnotationsIds: Array[String]): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
val envelope = BbbCoreEnvelope(DeleteWhiteboardAnnotationsEvtMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(DeleteWhiteboardAnnotationsEvtMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(DeleteWhiteboardAnnotationsEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
val header = BbbClientMsgHeader(DeleteWhiteboardAnnotationsEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ trait GetWhiteboardAnnotationsReqMsgHdlr {
|
|||||||
def handle(msg: GetWhiteboardAnnotationsReqMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handle(msg: GetWhiteboardAnnotationsReqMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(msg: GetWhiteboardAnnotationsReqMsg, history: Array[AnnotationVO], multiUser: Array[String]): Unit = {
|
def broadcastEvent(msg: GetWhiteboardAnnotationsReqMsg, history: Array[AnnotationVO], multiUser: Array[String]): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
|
||||||
val envelope = BbbCoreEnvelope(GetWhiteboardAnnotationsRespMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(GetWhiteboardAnnotationsRespMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(GetWhiteboardAnnotationsRespMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
val header = BbbClientMsgHeader(GetWhiteboardAnnotationsRespMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
@ -11,7 +11,7 @@ trait ModifyWhiteboardAccessPubMsgHdlr extends RightsManagementTrait {
|
|||||||
def handle(msg: ModifyWhiteboardAccessPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handle(msg: ModifyWhiteboardAccessPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(msg: ModifyWhiteboardAccessPubMsg): Unit = {
|
def broadcastEvent(msg: ModifyWhiteboardAccessPubMsg): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
val envelope = BbbCoreEnvelope(ModifyWhiteboardAccessEvtMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(ModifyWhiteboardAccessEvtMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(ModifyWhiteboardAccessEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
val header = BbbClientMsgHeader(ModifyWhiteboardAccessEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ trait SendCursorPositionPubMsgHdlr extends RightsManagementTrait {
|
|||||||
def handle(msg: SendCursorPositionPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handle(msg: SendCursorPositionPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(msg: SendCursorPositionPubMsg): Unit = {
|
def broadcastEvent(msg: SendCursorPositionPubMsg): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, liveMeeting.props.systemProps.html5InstanceId.toString)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
val envelope = BbbCoreEnvelope(SendCursorPositionEvtMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SendCursorPositionEvtMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SendCursorPositionEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
val header = BbbClientMsgHeader(SendCursorPositionEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ trait SendWhiteboardAnnotationsPubMsgHdlr extends RightsManagementTrait {
|
|||||||
|
|
||||||
def handle(msg: SendWhiteboardAnnotationsPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
def handle(msg: SendWhiteboardAnnotationsPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(msg: SendWhiteboardAnnotationsPubMsg, whiteboardId: String, annotations: Array[AnnotationVO], html5InstanceId: String): Unit = {
|
def broadcastEvent(msg: SendWhiteboardAnnotationsPubMsg, whiteboardId: String, annotations: Array[AnnotationVO]): Unit = {
|
||||||
val routing = Routing.addMsgToHtml5InstanceIdRouting(liveMeeting.props.meetingProp.intId, html5InstanceId)
|
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
val envelope = BbbCoreEnvelope(SendWhiteboardAnnotationsEvtMsg.NAME, routing)
|
val envelope = BbbCoreEnvelope(SendWhiteboardAnnotationsEvtMsg.NAME, routing)
|
||||||
val header = BbbClientMsgHeader(SendWhiteboardAnnotationsEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
val header = BbbClientMsgHeader(SendWhiteboardAnnotationsEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ trait SendWhiteboardAnnotationsPubMsgHdlr extends RightsManagementTrait {
|
|||||||
// }
|
// }
|
||||||
// println("============= Printed Sanitized annotations ============")
|
// println("============= Printed Sanitized annotations ============")
|
||||||
val annotations = sendWhiteboardAnnotations(msg.body.whiteboardId, msg.header.userId, msg.body.annotations, liveMeeting, isUserAmongPresenters, isUserModerator)
|
val annotations = sendWhiteboardAnnotations(msg.body.whiteboardId, msg.header.userId, msg.body.annotations, liveMeeting, isUserAmongPresenters, isUserModerator)
|
||||||
broadcastEvent(msg, msg.body.whiteboardId, annotations, msg.body.html5InstanceId)
|
broadcastEvent(msg, msg.body.whiteboardId, annotations)
|
||||||
} else {
|
} else {
|
||||||
//val meetingId = liveMeeting.props.meetingProp.intId
|
//val meetingId = liveMeeting.props.meetingProp.intId
|
||||||
//val reason = "No permission to send a whiteboard annotation."
|
//val reason = "No permission to send a whiteboard annotation."
|
||||||
|
@ -18,27 +18,18 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender)
|
|||||||
case _ => log.warning("Cannot handle message ")
|
case _ => log.warning("Cannot handle message ")
|
||||||
}
|
}
|
||||||
|
|
||||||
def sendToHTML5InstanceIdChannel(msg: BbbCommonEnvCoreMsg, json: String): Unit = {
|
|
||||||
msg.envelope.routing.get("html5InstanceId") match {
|
|
||||||
case Some(id) => {
|
|
||||||
msgSender.send(toHTML5RedisChannel.concat(id), json)
|
|
||||||
}
|
|
||||||
case _ => log.error("No html5InstanceId for " + msg.envelope.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
||||||
val json = JsonUtil.toJson(msg)
|
val json = JsonUtil.toJson(msg)
|
||||||
|
|
||||||
msg.envelope.name match {
|
msg.envelope.name match {
|
||||||
|
|
||||||
// HTML5 sync messages
|
// HTML5 sync messages
|
||||||
case SyncGetPresentationPodsRespMsg.NAME => sendToHTML5InstanceIdChannel(msg, json)
|
case SyncGetPresentationPodsRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||||
case SyncGetMeetingInfoRespMsg.NAME => sendToHTML5InstanceIdChannel(msg, json)
|
case SyncGetMeetingInfoRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||||
case SyncGetUsersMeetingRespMsg.NAME => sendToHTML5InstanceIdChannel(msg, json)
|
case SyncGetUsersMeetingRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||||
case SyncGetGroupChatsRespMsg.NAME => sendToHTML5InstanceIdChannel(msg, json)
|
case SyncGetGroupChatsRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||||
case SyncGetGroupChatMsgsRespMsg.NAME => sendToHTML5InstanceIdChannel(msg, json)
|
case SyncGetGroupChatMsgsRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||||
case SyncGetVoiceUsersRespMsg.NAME => sendToHTML5InstanceIdChannel(msg, json)
|
case SyncGetVoiceUsersRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||||
|
|
||||||
// Sent to FreeSWITCH
|
// Sent to FreeSWITCH
|
||||||
case EjectAllFromVoiceConfMsg.NAME =>
|
case EjectAllFromVoiceConfMsg.NAME =>
|
||||||
|
@ -68,7 +68,6 @@ case class LockSettingsProps(
|
|||||||
)
|
)
|
||||||
|
|
||||||
case class SystemProps(
|
case class SystemProps(
|
||||||
html5InstanceId: Int,
|
|
||||||
loginUrl: String,
|
loginUrl: String,
|
||||||
logoutUrl: String,
|
logoutUrl: String,
|
||||||
customLogoURL: String,
|
customLogoURL: String,
|
||||||
|
@ -4,7 +4,6 @@ object Routing {
|
|||||||
val MSG_TYPE = "msgType"
|
val MSG_TYPE = "msgType"
|
||||||
val MEETING_ID = "meetingId"
|
val MEETING_ID = "meetingId"
|
||||||
val USER_ID = "userId"
|
val USER_ID = "userId"
|
||||||
val HTML5_INSTANCE_ID = "html5InstanceId"
|
|
||||||
|
|
||||||
def addMsgToClientRouting(msgType: String, meetingId: String, userId: String): collection.immutable.Map[String, String] = {
|
def addMsgToClientRouting(msgType: String, meetingId: String, userId: String): collection.immutable.Map[String, String] = {
|
||||||
Map(MSG_TYPE -> msgType, MEETING_ID -> meetingId, USER_ID -> userId)
|
Map(MSG_TYPE -> msgType, MEETING_ID -> meetingId, USER_ID -> userId)
|
||||||
@ -13,10 +12,6 @@ object Routing {
|
|||||||
def addMsgFromClientRouting(meetingId: String, userId: String): collection.immutable.Map[String, String] = {
|
def addMsgFromClientRouting(meetingId: String, userId: String): collection.immutable.Map[String, String] = {
|
||||||
Map(MEETING_ID -> meetingId, USER_ID -> userId)
|
Map(MEETING_ID -> meetingId, USER_ID -> userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
def addMsgToHtml5InstanceIdRouting(meetingId: String, html5InstanceId: String): collection.immutable.Map[String, String] = {
|
|
||||||
Map(MEETING_ID -> meetingId, HTML5_INSTANCE_ID -> html5InstanceId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Routing {
|
class Routing {
|
||||||
|
@ -35,7 +35,7 @@ case class GetAllMeetingsReqMsg(
|
|||||||
header: BbbCoreBaseHeader,
|
header: BbbCoreBaseHeader,
|
||||||
body: GetAllMeetingsReqMsgBody
|
body: GetAllMeetingsReqMsgBody
|
||||||
) extends BbbCoreMsg
|
) extends BbbCoreMsg
|
||||||
case class GetAllMeetingsReqMsgBody(requesterId: String, html5InstanceId: Int)
|
case class GetAllMeetingsReqMsgBody(requesterId: String)
|
||||||
|
|
||||||
object GetRunningMeetingsReqMsg { val NAME = "GetRunningMeetingsReqMsg" }
|
object GetRunningMeetingsReqMsg { val NAME = "GetRunningMeetingsReqMsg" }
|
||||||
case class GetRunningMeetingsReqMsg(
|
case class GetRunningMeetingsReqMsg(
|
||||||
|
@ -54,7 +54,7 @@ case class SendCursorPositionPubMsgBody(whiteboardId: String, xPercent: Double,
|
|||||||
|
|
||||||
object SendWhiteboardAnnotationsPubMsg { val NAME = "SendWhiteboardAnnotationsPubMsg" }
|
object SendWhiteboardAnnotationsPubMsg { val NAME = "SendWhiteboardAnnotationsPubMsg" }
|
||||||
case class SendWhiteboardAnnotationsPubMsg(header: BbbClientMsgHeader, body: SendWhiteboardAnnotationsPubMsgBody) extends StandardMsg
|
case class SendWhiteboardAnnotationsPubMsg(header: BbbClientMsgHeader, body: SendWhiteboardAnnotationsPubMsgBody) extends StandardMsg
|
||||||
case class SendWhiteboardAnnotationsPubMsgBody(whiteboardId: String, annotations: Array[AnnotationVO], html5InstanceId: String)
|
case class SendWhiteboardAnnotationsPubMsgBody(whiteboardId: String, annotations: Array[AnnotationVO])
|
||||||
|
|
||||||
object DeleteWhiteboardAnnotationsPubMsg { val NAME = "DeleteWhiteboardAnnotationsPubMsg" }
|
object DeleteWhiteboardAnnotationsPubMsg { val NAME = "DeleteWhiteboardAnnotationsPubMsg" }
|
||||||
case class DeleteWhiteboardAnnotationsPubMsg(header: BbbClientMsgHeader, body: DeleteWhiteboardAnnotationsPubMsgBody) extends StandardMsg
|
case class DeleteWhiteboardAnnotationsPubMsg(header: BbbClientMsgHeader, body: DeleteWhiteboardAnnotationsPubMsgBody) extends StandardMsg
|
||||||
|
@ -68,7 +68,6 @@ public class ApiParams {
|
|||||||
public static final String MEETING_EXPIRE_IF_NO_USER_JOINED_IN_MINUTES = "meetingExpireIfNoUserJoinedInMinutes";
|
public static final String MEETING_EXPIRE_IF_NO_USER_JOINED_IN_MINUTES = "meetingExpireIfNoUserJoinedInMinutes";
|
||||||
public static final String MEETING_EXPIRE_WHEN_LAST_USER_LEFT_IN_MINUTES = "meetingExpireWhenLastUserLeftInMinutes";
|
public static final String MEETING_EXPIRE_WHEN_LAST_USER_LEFT_IN_MINUTES = "meetingExpireWhenLastUserLeftInMinutes";
|
||||||
public static final String WELCOME = "welcome";
|
public static final String WELCOME = "welcome";
|
||||||
public static final String HTML5_INSTANCE_ID = "html5InstanceId";
|
|
||||||
public static final String ROLE = "role";
|
public static final String ROLE = "role";
|
||||||
public static final String GROUPS = "groups";
|
public static final String GROUPS = "groups";
|
||||||
public static final String DISABLED_FEATURES = "disabledFeatures";
|
public static final String DISABLED_FEATURES = "disabledFeatures";
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
/**
|
|
||||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
|
||||||
* <p>
|
|
||||||
* Copyright (c) 2020 BigBlueButton Inc. and by respective authors (see below).
|
|
||||||
* <p>
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
|
||||||
* version.
|
|
||||||
* <p>
|
|
||||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
* <p>
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along
|
|
||||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.bigbluebutton.api;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.bigbluebutton.api.util.HTML5ProcessLine;
|
|
||||||
|
|
||||||
|
|
||||||
public class HTML5LoadBalancingService {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(HTML5LoadBalancingService.class);
|
|
||||||
private ArrayList<HTML5ProcessLine> list = new ArrayList<HTML5ProcessLine>();
|
|
||||||
private final int MAX_NUMBER_OF_HTML5_INSTANCES = 20;
|
|
||||||
private int lastSelectedInstanceId = 0;
|
|
||||||
|
|
||||||
public void init() {
|
|
||||||
log.info("HTML5LoadBalancingService initialised");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find nodejs processes associated with processing meeting events
|
|
||||||
// $ ps -u meteor -o pcpu,cmd= | grep NODEJS_BACKEND_INSTANCE_ID
|
|
||||||
// 1.1 /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js NODEJS_BACKEND_INSTANCE_ID=1
|
|
||||||
// 1.0 /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js NODEJS_BACKEND_INSTANCE_ID=2
|
|
||||||
public void scanHTML5processes() {
|
|
||||||
try {
|
|
||||||
this.list = new ArrayList<HTML5ProcessLine>();
|
|
||||||
Process p1 = Runtime.getRuntime().exec(new String[]{"ps", "-u", "meteor", "-o", "pcpu,cmd="});
|
|
||||||
InputStream input1 = p1.getInputStream();
|
|
||||||
Process p2 = Runtime.getRuntime().exec(new String[]{"grep", HTML5ProcessLine.BBB_HTML5_PROCESS_IDENTIFIER});
|
|
||||||
OutputStream output = p2.getOutputStream();
|
|
||||||
IOUtils.copy(input1, output);
|
|
||||||
output.close(); // signals grep to finish
|
|
||||||
List<String> result = IOUtils.readLines(p2.getInputStream());
|
|
||||||
for (String entry : result) {
|
|
||||||
HTML5ProcessLine line = new HTML5ProcessLine(entry);
|
|
||||||
list.add(line);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean listItemWithIdExists(int id) {
|
|
||||||
for (HTML5ProcessLine line : this.list) {
|
|
||||||
if (line.instanceId == id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int findSuitableHTML5ProcessByRoundRobin() {
|
|
||||||
this.scanHTML5processes();
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
log.warn("Did not find any instances of html5 process running");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = lastSelectedInstanceId + 1; i <= MAX_NUMBER_OF_HTML5_INSTANCES + lastSelectedInstanceId; i++) {
|
|
||||||
int k = i % (MAX_NUMBER_OF_HTML5_INSTANCES + 1);
|
|
||||||
if (this.listItemWithIdExists(k)) {
|
|
||||||
this.lastSelectedInstanceId = k;
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -452,7 +452,7 @@ public class MeetingService implements MessageListener {
|
|||||||
m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(),
|
m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(),
|
||||||
m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(),
|
m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(),
|
||||||
m.getMuteOnStart(), m.getAllowModsToUnmuteUsers(), m.getAllowModsToEjectCameras(), m.getMeetingKeepEvents(),
|
m.getMuteOnStart(), m.getAllowModsToUnmuteUsers(), m.getAllowModsToEjectCameras(), m.getMeetingKeepEvents(),
|
||||||
m.breakoutRoomsParams, m.lockSettingsParams, m.getHtml5InstanceId(), m.getLoginUrl(), m.getLogoutUrl(), m.getCustomLogoURL(),
|
m.breakoutRoomsParams, m.lockSettingsParams, m.getLoginUrl(), m.getLogoutUrl(), m.getCustomLogoURL(),
|
||||||
m.getBannerText(), m.getBannerColor(), m.getGroups(), m.getDisabledFeatures(), m.getNotifyRecordingIsOn(),
|
m.getBannerText(), m.getBannerColor(), m.getGroups(), m.getDisabledFeatures(), m.getNotifyRecordingIsOn(),
|
||||||
m.getPresentationUploadExternalDescription(), m.getPresentationUploadExternalUrl(),
|
m.getPresentationUploadExternalDescription(), m.getPresentationUploadExternalUrl(),
|
||||||
m.getOverrideClientSettings());
|
m.getOverrideClientSettings());
|
||||||
|
@ -134,7 +134,6 @@ public class ParamsProcessorUtil {
|
|||||||
private Integer maxUserConcurrentAccesses = 0;
|
private Integer maxUserConcurrentAccesses = 0;
|
||||||
private Boolean defaultEndWhenNoModerator = false;
|
private Boolean defaultEndWhenNoModerator = false;
|
||||||
private Integer defaultEndWhenNoModeratorDelayInMinutes = 1;
|
private Integer defaultEndWhenNoModeratorDelayInMinutes = 1;
|
||||||
private Integer defaultHtml5InstanceId = 1;
|
|
||||||
|
|
||||||
private String bbbVersion = "";
|
private String bbbVersion = "";
|
||||||
private Boolean allowRevealOfBBBVersion = false;
|
private Boolean allowRevealOfBBBVersion = false;
|
||||||
@ -731,8 +730,6 @@ public class ParamsProcessorUtil {
|
|||||||
|
|
||||||
String avatarURL = useDefaultAvatar ? defaultAvatarURL : "";
|
String avatarURL = useDefaultAvatar ? defaultAvatarURL : "";
|
||||||
|
|
||||||
int html5InstanceId = processHtml5InstanceId(params.get(ApiParams.HTML5_INSTANCE_ID));
|
|
||||||
|
|
||||||
if(defaultAllowDuplicateExtUserid == false) {
|
if(defaultAllowDuplicateExtUserid == false) {
|
||||||
log.warn("[DEPRECATION] use `maxUserConcurrentAccesses=1` instead of `allowDuplicateExtUserid=false`");
|
log.warn("[DEPRECATION] use `maxUserConcurrentAccesses=1` instead of `allowDuplicateExtUserid=false`");
|
||||||
maxUserConcurrentAccesses = 1;
|
maxUserConcurrentAccesses = 1;
|
||||||
@ -768,7 +765,6 @@ public class ParamsProcessorUtil {
|
|||||||
.withBreakoutRoomsParams(breakoutParams)
|
.withBreakoutRoomsParams(breakoutParams)
|
||||||
.withLockSettingsParams(lockSettingsParams)
|
.withLockSettingsParams(lockSettingsParams)
|
||||||
.withMaxUserConcurrentAccesses(maxUserConcurrentAccesses)
|
.withMaxUserConcurrentAccesses(maxUserConcurrentAccesses)
|
||||||
.withHTML5InstanceId(html5InstanceId)
|
|
||||||
.withLearningDashboardCleanupDelayInMinutes(learningDashboardCleanupMins)
|
.withLearningDashboardCleanupDelayInMinutes(learningDashboardCleanupMins)
|
||||||
.withLearningDashboardAccessToken(learningDashboardAccessToken)
|
.withLearningDashboardAccessToken(learningDashboardAccessToken)
|
||||||
.withGroups(groups)
|
.withGroups(groups)
|
||||||
@ -795,7 +791,6 @@ public class ParamsProcessorUtil {
|
|||||||
meeting.setUserInactivityInspectTimerInMinutes(userInactivityInspectTimerInMinutes);
|
meeting.setUserInactivityInspectTimerInMinutes(userInactivityInspectTimerInMinutes);
|
||||||
meeting.setUserActivitySignResponseDelayInMinutes(userActivitySignResponseDelayInMinutes);
|
meeting.setUserActivitySignResponseDelayInMinutes(userActivitySignResponseDelayInMinutes);
|
||||||
meeting.setUserInactivityThresholdInMinutes(userInactivityThresholdInMinutes);
|
meeting.setUserInactivityThresholdInMinutes(userInactivityThresholdInMinutes);
|
||||||
// meeting.setHtml5InstanceId(html5InstanceId);
|
|
||||||
meeting.setEndWhenNoModerator(endWhenNoModerator);
|
meeting.setEndWhenNoModerator(endWhenNoModerator);
|
||||||
meeting.setEndWhenNoModeratorDelayInMinutes(endWhenNoModeratorDelayInMinutes);
|
meeting.setEndWhenNoModeratorDelayInMinutes(endWhenNoModeratorDelayInMinutes);
|
||||||
|
|
||||||
@ -978,17 +973,6 @@ public class ParamsProcessorUtil {
|
|||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int processHtml5InstanceId(String instanceId) {
|
|
||||||
int html5InstanceId = 1;
|
|
||||||
try {
|
|
||||||
html5InstanceId = Integer.parseInt(instanceId);
|
|
||||||
} catch(Exception ex) {
|
|
||||||
html5InstanceId = defaultHtml5InstanceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html5InstanceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int processMaxUser(String maxUsers) {
|
public int processMaxUser(String maxUsers) {
|
||||||
int mUsers = -1;
|
int mUsers = -1;
|
||||||
|
|
||||||
|
@ -117,8 +117,6 @@ public class Meeting {
|
|||||||
|
|
||||||
private String meetingEndedCallbackURL = "";
|
private String meetingEndedCallbackURL = "";
|
||||||
|
|
||||||
private Integer html5InstanceId;
|
|
||||||
|
|
||||||
private String overrideClientSettings = "";
|
private String overrideClientSettings = "";
|
||||||
|
|
||||||
public Meeting(Meeting.Builder builder) {
|
public Meeting(Meeting.Builder builder) {
|
||||||
@ -174,7 +172,6 @@ public class Meeting {
|
|||||||
maxUserConcurrentAccesses = builder.maxUserConcurrentAccesses;
|
maxUserConcurrentAccesses = builder.maxUserConcurrentAccesses;
|
||||||
endWhenNoModerator = builder.endWhenNoModerator;
|
endWhenNoModerator = builder.endWhenNoModerator;
|
||||||
endWhenNoModeratorDelayInMinutes = builder.endWhenNoModeratorDelayInMinutes;
|
endWhenNoModeratorDelayInMinutes = builder.endWhenNoModeratorDelayInMinutes;
|
||||||
html5InstanceId = builder.html5InstanceId;
|
|
||||||
groups = builder.groups;
|
groups = builder.groups;
|
||||||
guestUsersWithPositionInWaitingLine = new HashMap<>();
|
guestUsersWithPositionInWaitingLine = new HashMap<>();
|
||||||
userCustomData = new HashMap<>();
|
userCustomData = new HashMap<>();
|
||||||
@ -286,10 +283,6 @@ public class Meeting {
|
|||||||
return GuestPolicy.DENY;
|
return GuestPolicy.DENY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHtml5InstanceId() { return html5InstanceId; }
|
|
||||||
|
|
||||||
public void setHtml5InstanceId(int instanceId) { html5InstanceId = instanceId; }
|
|
||||||
|
|
||||||
public ArrayList<Group> getGroups() { return groups; }
|
public ArrayList<Group> getGroups() { return groups; }
|
||||||
|
|
||||||
public void setGroups(ArrayList<Group> groups) { this.groups = groups; }
|
public void setGroups(ArrayList<Group> groups) { this.groups = groups; }
|
||||||
@ -925,7 +918,6 @@ public class Meeting {
|
|||||||
private Integer maxUserConcurrentAccesses;
|
private Integer maxUserConcurrentAccesses;
|
||||||
private Boolean endWhenNoModerator;
|
private Boolean endWhenNoModerator;
|
||||||
private Integer endWhenNoModeratorDelayInMinutes;
|
private Integer endWhenNoModeratorDelayInMinutes;
|
||||||
private int html5InstanceId;
|
|
||||||
private ArrayList<Group> groups;
|
private ArrayList<Group> groups;
|
||||||
|
|
||||||
public Builder(String externalId, String internalId, long createTime) {
|
public Builder(String externalId, String internalId, long createTime) {
|
||||||
@ -1139,11 +1131,6 @@ public class Meeting {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withHTML5InstanceId(int instanceId) {
|
|
||||||
html5InstanceId = instanceId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder withGroups(ArrayList<Group> groups) {
|
public Builder withGroups(ArrayList<Group> groups) {
|
||||||
this.groups = groups;
|
this.groups = groups;
|
||||||
return this;
|
return this;
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
|
||||||
* <p>
|
|
||||||
* Copyright (c) 2020 BigBlueButton Inc. and by respective authors (see below).
|
|
||||||
* <p>
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
|
||||||
* version.
|
|
||||||
* <p>
|
|
||||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
* <p>
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along
|
|
||||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.bigbluebutton.api.util;
|
|
||||||
|
|
||||||
public class HTML5ProcessLine {
|
|
||||||
|
|
||||||
public int instanceId;
|
|
||||||
public double percentageCPU;
|
|
||||||
|
|
||||||
public static final String BBB_HTML5_PROCESS_IDENTIFIER = "NODEJS_BACKEND_INSTANCE_ID";
|
|
||||||
|
|
||||||
public HTML5ProcessLine(String input) {
|
|
||||||
// $ ps -u meteor -o pcpu,cmd= | grep NODEJS_BACKEND_INSTANCE_ID
|
|
||||||
// 1.1 /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js NODEJS_BACKEND_INSTANCE_ID=1
|
|
||||||
// 1.0 /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js NODEJS_BACKEND_INSTANCE_ID=2
|
|
||||||
|
|
||||||
String[] a = input.trim().split(" ");
|
|
||||||
this.percentageCPU = Double.parseDouble(a[0]);
|
|
||||||
|
|
||||||
for (int i = 0; i < a.length; i++) {
|
|
||||||
if (a[i].toString().indexOf(BBB_HTML5_PROCESS_IDENTIFIER) > -1) {
|
|
||||||
this.instanceId = Integer.parseInt(a[i].replace(BBB_HTML5_PROCESS_IDENTIFIER + "=", ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "instanceId:" + this.instanceId + " CPU:" + this.percentageCPU;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -41,7 +41,6 @@ public interface IBbbWebApiGWApp {
|
|||||||
Boolean keepEvents,
|
Boolean keepEvents,
|
||||||
BreakoutRoomsParams breakoutParams,
|
BreakoutRoomsParams breakoutParams,
|
||||||
LockSettingsParams lockSettingsParams,
|
LockSettingsParams lockSettingsParams,
|
||||||
Integer html5InstanceId,
|
|
||||||
String loginUrl,
|
String loginUrl,
|
||||||
String logoutUrl,
|
String logoutUrl,
|
||||||
String customLogoURL,
|
String customLogoURL,
|
||||||
|
@ -148,7 +148,6 @@ class BbbWebApiGWApp(
|
|||||||
keepEvents: java.lang.Boolean,
|
keepEvents: java.lang.Boolean,
|
||||||
breakoutParams: BreakoutRoomsParams,
|
breakoutParams: BreakoutRoomsParams,
|
||||||
lockSettingsParams: LockSettingsParams,
|
lockSettingsParams: LockSettingsParams,
|
||||||
html5InstanceId: java.lang.Integer,
|
|
||||||
loginUrl: String,
|
loginUrl: String,
|
||||||
logoutUrl: String,
|
logoutUrl: String,
|
||||||
customLogoURL: String,
|
customLogoURL: String,
|
||||||
@ -235,7 +234,6 @@ class BbbWebApiGWApp(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val systemProps = SystemProps(
|
val systemProps = SystemProps(
|
||||||
html5InstanceId,
|
|
||||||
loginUrl match {
|
loginUrl match {
|
||||||
case url: String => url
|
case url: String => url
|
||||||
case _ => ""
|
case _ => ""
|
||||||
|
@ -22,7 +22,6 @@ export default function buildRedisMessage(sessionVariables: Record<string, unkno
|
|||||||
const body = {
|
const body = {
|
||||||
whiteboardId: input.pageId,
|
whiteboardId: input.pageId,
|
||||||
annotations: input.annotations,
|
annotations: input.annotations,
|
||||||
html5InstanceId: '', //TODO remove this prop from bbb-common-msg
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return { eventName, routing, header, body };
|
return { eventName, routing, header, body };
|
||||||
|
@ -9,7 +9,6 @@ export default function MeetingInfo() {
|
|||||||
disabledFeatures
|
disabledFeatures
|
||||||
durationInSeconds
|
durationInSeconds
|
||||||
extId
|
extId
|
||||||
html5InstanceId
|
|
||||||
isBreakout
|
isBreakout
|
||||||
maxPinnedCameras
|
maxPinnedCameras
|
||||||
meetingCameraCap
|
meetingCameraCap
|
||||||
|
@ -19,7 +19,6 @@ create table "meeting" (
|
|||||||
"presentationUploadExternalDescription" text,
|
"presentationUploadExternalDescription" text,
|
||||||
"presentationUploadExternalUrl" varchar(500),
|
"presentationUploadExternalUrl" varchar(500),
|
||||||
"learningDashboardAccessToken" varchar(100),
|
"learningDashboardAccessToken" varchar(100),
|
||||||
"html5InstanceId" varchar(100),
|
|
||||||
"loginUrl" varchar(500),
|
"loginUrl" varchar(500),
|
||||||
"logoutUrl" varchar(500),
|
"logoutUrl" varchar(500),
|
||||||
"customLogoUrl" varchar(500),
|
"customLogoUrl" varchar(500),
|
||||||
|
@ -171,7 +171,6 @@ select_permissions:
|
|||||||
- endedByUserName
|
- endedByUserName
|
||||||
- endedReasonCode
|
- endedReasonCode
|
||||||
- extId
|
- extId
|
||||||
- html5InstanceId
|
|
||||||
- isBreakout
|
- isBreakout
|
||||||
- loginUrl
|
- loginUrl
|
||||||
- logoutUrl
|
- logoutUrl
|
||||||
|
@ -380,20 +380,6 @@ display_bigbluebutton_status () {
|
|||||||
|
|
||||||
if [ -f /usr/lib/systemd/system/bbb-html5.service ]; then
|
if [ -f /usr/lib/systemd/system/bbb-html5.service ]; then
|
||||||
units="$units mongod bbb-html5"
|
units="$units mongod bbb-html5"
|
||||||
|
|
||||||
source /usr/share/meteor/bundle/bbb-html5-with-roles.conf
|
|
||||||
|
|
||||||
if [ -f /etc/bigbluebutton/bbb-html5-with-roles.conf ]; then
|
|
||||||
source /etc/bigbluebutton/bbb-html5-with-roles.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
for ((i = 1 ; i <= $NUMBER_OF_BACKEND_NODEJS_PROCESSES; i++)); do
|
|
||||||
units="$units bbb-html5-backend@$i"
|
|
||||||
done
|
|
||||||
|
|
||||||
for ((i = 1; i <= $NUMBER_OF_FRONTEND_NODEJS_PROCESSES; i++)); do
|
|
||||||
units="$units bbb-html5-frontend@$i"
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f /usr/lib/systemd/system/bbb-graphql-actions.service ]; then
|
if [ -f /usr/lib/systemd/system/bbb-graphql-actions.service ]; then
|
||||||
|
@ -16,7 +16,7 @@ fi
|
|||||||
|
|
||||||
sudo rm -rf "$UPPER_DESTINATION_DIR"
|
sudo rm -rf "$UPPER_DESTINATION_DIR"
|
||||||
sudo mkdir -p "$UPPER_DESTINATION_DIR"
|
sudo mkdir -p "$UPPER_DESTINATION_DIR"
|
||||||
sudo chown -R meteor:meteor "$UPPER_DESTINATION_DIR"
|
sudo chown -R root:root "$UPPER_DESTINATION_DIR"
|
||||||
|
|
||||||
# the next 5 lines may be temporarily commented out if you are sure you are not tweaking the required node_modules after first use of the script. This will save a minute or two during the run of the script
|
# the next 5 lines may be temporarily commented out if you are sure you are not tweaking the required node_modules after first use of the script. This will save a minute or two during the run of the script
|
||||||
if [ -d "node_modules" ]; then
|
if [ -d "node_modules" ]; then
|
||||||
@ -28,10 +28,9 @@ meteor npm ci --production
|
|||||||
sudo chmod 777 /usr/share/meteor
|
sudo chmod 777 /usr/share/meteor
|
||||||
METEOR_DISABLE_OPTIMISTIC_CACHING=1 meteor build $UPPER_DESTINATION_DIR --architecture os.linux.x86_64 --allow-superuser --directory
|
METEOR_DISABLE_OPTIMISTIC_CACHING=1 meteor build $UPPER_DESTINATION_DIR --architecture os.linux.x86_64 --allow-superuser --directory
|
||||||
|
|
||||||
sudo chown -R meteor:meteor "$UPPER_DESTINATION_DIR"/
|
sudo chown -R root:root "$UPPER_DESTINATION_DIR"/
|
||||||
echo 'stage3'
|
echo 'stage3'
|
||||||
|
|
||||||
|
|
||||||
cd "$DESTINATION_DIR"/programs/server/ || exit
|
cd "$DESTINATION_DIR"/programs/server/ || exit
|
||||||
sudo chmod -R 777 .
|
sudo chmod -R 777 .
|
||||||
meteor npm i
|
meteor npm i
|
||||||
@ -44,63 +43,15 @@ sudo cp $LOCAL_PACKAGING_DIR/mongod_start_pre.sh "$DESTINATION_DIR"/mongod_start
|
|||||||
echo "writing $DESTINATION_DIR/mongo-ramdisk.conf"
|
echo "writing $DESTINATION_DIR/mongo-ramdisk.conf"
|
||||||
sudo cp $LOCAL_PACKAGING_DIR/mongo-ramdisk.conf "$DESTINATION_DIR"/mongo-ramdisk.conf
|
sudo cp $LOCAL_PACKAGING_DIR/mongo-ramdisk.conf "$DESTINATION_DIR"/mongo-ramdisk.conf
|
||||||
|
|
||||||
echo "writing $DESTINATION_DIR/bbb-html5-with-roles.conf"
|
sudo chown -R root:root "$UPPER_DESTINATION_DIR"/
|
||||||
sudo tee "$DESTINATION_DIR/bbb-html5-with-roles.conf" >/dev/null <<HERE
|
|
||||||
# Default = 2; Min = 1; Max = 4
|
|
||||||
# On powerful systems with high number of meetings you can set values up to 4 to accelerate handling of events
|
|
||||||
NUMBER_OF_BACKEND_NODEJS_PROCESSES=2
|
|
||||||
# Default = 2; Min = 0; Max = 8
|
|
||||||
# If 0 is set, bbb-html5 will handle both backend and frontend roles in one process (default until Feb 2021)
|
|
||||||
# Set a number between 1 and 4 times the value of NUMBER_OF_BACKEND_NODEJS_PROCESSES where higher number helps with meetings
|
|
||||||
# stretching the recommended number of users in BigBlueButton
|
|
||||||
NUMBER_OF_FRONTEND_NODEJS_PROCESSES=2
|
|
||||||
|
|
||||||
HERE
|
|
||||||
|
|
||||||
echo "writing $DESTINATION_DIR/systemd_start.sh"
|
|
||||||
sudo cp $LOCAL_PACKAGING_DIR/systemd_start.sh "$DESTINATION_DIR"/systemd_start.sh
|
|
||||||
|
|
||||||
echo "writing $DESTINATION_DIR/systemd_start_frontend.sh"
|
|
||||||
sudo cp $LOCAL_PACKAGING_DIR/systemd_start_frontend.sh "$DESTINATION_DIR"/systemd_start_frontend.sh
|
|
||||||
|
|
||||||
sudo chown -R meteor:meteor "$UPPER_DESTINATION_DIR"/
|
|
||||||
sudo chmod +x "$DESTINATION_DIR"/mongod_start_pre.sh
|
sudo chmod +x "$DESTINATION_DIR"/mongod_start_pre.sh
|
||||||
sudo chmod +x "$DESTINATION_DIR"/systemd_start.sh
|
|
||||||
sudo chmod +x "$DESTINATION_DIR"/systemd_start_frontend.sh
|
|
||||||
|
|
||||||
sudo cp $LOCAL_PACKAGING_DIR/workers-start.sh "$DESTINATION_DIR"/workers-start.sh
|
sudo cp $LOCAL_PACKAGING_DIR/workers-start.sh "$DESTINATION_DIR"/workers-start.sh
|
||||||
sudo chmod +x "$DESTINATION_DIR"/workers-start.sh
|
sudo chmod +x "$DESTINATION_DIR"/workers-start.sh
|
||||||
|
|
||||||
|
echo "writing $SERVICE_FILES_DIR/bbb-html5.service"
|
||||||
|
sudo cp $LOCAL_PACKAGING_DIR/bbb-html5.service "$SERVICE_FILES_DIR"/bbb-html5.service
|
||||||
echo "writing $SERVICE_FILES_DIR/bbb-html5-frontend@.service"
|
|
||||||
sudo cp $LOCAL_PACKAGING_DIR/bbb-html5-frontend@.service "$SERVICE_FILES_DIR"/bbb-html5-frontend@.service
|
|
||||||
|
|
||||||
echo "writing $SERVICE_FILES_DIR/bbb-html5-backend@.service"
|
|
||||||
sudo cp $LOCAL_PACKAGING_DIR/bbb-html5-backend@.service "$SERVICE_FILES_DIR"/bbb-html5-backend@.service
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
|
|
||||||
echo 'before stopping bbb-html5:'
|
sudo systemctl restart bbb-html5
|
||||||
ps -ef | grep node-
|
|
||||||
sudo ss -netlp | grep -i node
|
|
||||||
echo 'before stopping bbb-html5:'
|
|
||||||
echo '_____________'
|
|
||||||
|
|
||||||
sudo systemctl stop bbb-html5
|
|
||||||
|
|
||||||
sleep 5s
|
|
||||||
echo 'after stopping bbb-html5:'
|
|
||||||
ps -ef | grep node-
|
|
||||||
sudo ss -netlp | grep -i node
|
|
||||||
echo 'after stopping bbb-html5:'
|
|
||||||
echo '_____________'
|
|
||||||
|
|
||||||
echo 'starting bbb-html5'
|
|
||||||
sudo systemctl start bbb-html5
|
|
||||||
sleep 10s
|
|
||||||
echo 'after:...'
|
|
||||||
ps -ef | grep node-
|
|
||||||
sudo ss -netlp | grep -i node
|
|
||||||
echo 'after:'
|
|
||||||
echo '_____________'
|
|
||||||
|
@ -115,7 +115,6 @@ export interface Meeting {
|
|||||||
disabledFeatures: Array<string>;
|
disabledFeatures: Array<string>;
|
||||||
durationInSeconds: number;
|
durationInSeconds: number;
|
||||||
extId: string;
|
extId: string;
|
||||||
html5InstanceId: string | null;
|
|
||||||
isBreakout: boolean;
|
isBreakout: boolean;
|
||||||
learningDashboardAccessToken: string;
|
learningDashboardAccessToken: string;
|
||||||
maxPinnedCameras: number;
|
maxPinnedCameras: number;
|
||||||
|
@ -97,7 +97,6 @@ const MEETING_SUBSCRIPTION = gql`
|
|||||||
record
|
record
|
||||||
sequence
|
sequence
|
||||||
}
|
}
|
||||||
html5InstanceId
|
|
||||||
voiceSettings {
|
voiceSettings {
|
||||||
dialNumber
|
dialNumber
|
||||||
muteOnStart
|
muteOnStart
|
||||||
|
2
bigbluebutton-html5/package-lock.json
generated
2
bigbluebutton-html5/package-lock.json
generated
@ -9432,4 +9432,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -118,8 +118,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
<property name="learningDashboardFilesDir" value="${learningDashboardFilesDir}"/>
|
<property name="learningDashboardFilesDir" value="${learningDashboardFilesDir}"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="html5LoadBalancingService" class="org.bigbluebutton.api.HTML5LoadBalancingService" init-method="init" />
|
|
||||||
|
|
||||||
<bean id="validationService" class="org.bigbluebutton.api.service.ValidationService">
|
<bean id="validationService" class="org.bigbluebutton.api.service.ValidationService">
|
||||||
<property name="securitySalt" value="${securitySalt}"/>
|
<property name="securitySalt" value="${securitySalt}"/>
|
||||||
<property name="supportedChecksumAlgorithms" value="${supportedChecksumAlgorithms}"/>
|
<property name="supportedChecksumAlgorithms" value="${supportedChecksumAlgorithms}"/>
|
||||||
|
@ -62,7 +62,6 @@ class ApiController {
|
|||||||
ParamsProcessorUtil paramsProcessorUtil
|
ParamsProcessorUtil paramsProcessorUtil
|
||||||
PresentationUrlDownloadService presDownloadService
|
PresentationUrlDownloadService presDownloadService
|
||||||
StunTurnService stunTurnService
|
StunTurnService stunTurnService
|
||||||
HTML5LoadBalancingService html5LoadBalancingService
|
|
||||||
ResponseBuilder responseBuilder = initResponseBuilder()
|
ResponseBuilder responseBuilder = initResponseBuilder()
|
||||||
ValidationService validationService
|
ValidationService validationService
|
||||||
|
|
||||||
@ -184,8 +183,6 @@ class ApiController {
|
|||||||
// Still no unique voiceBridge found? Let createMeeting handle it.
|
// Still no unique voiceBridge found? Let createMeeting handle it.
|
||||||
}
|
}
|
||||||
|
|
||||||
params.html5InstanceId = html5LoadBalancingService.findSuitableHTML5ProcessByRoundRobin().toString()
|
|
||||||
|
|
||||||
Meeting newMeeting = paramsProcessorUtil.processCreateParams(params)
|
Meeting newMeeting = paramsProcessorUtil.processCreateParams(params)
|
||||||
|
|
||||||
String requestBody = request.inputStream == null ? null : request.inputStream.text
|
String requestBody = request.inputStream == null ? null : request.inputStream.text
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=BigBlueButton HTML5 service, backend instance %i
|
|
||||||
Requires=bbb-html5.service
|
|
||||||
Before=bbb-html5.service
|
|
||||||
BindsTo=bbb-html5.service
|
|
||||||
StartLimitBurst=4
|
|
||||||
StartLimitInterval=70sec
|
|
||||||
StartLimitAction=none
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
PermissionsStartOnly=true
|
|
||||||
#Type=simple
|
|
||||||
Type=idle
|
|
||||||
EnvironmentFile=/usr/share/meteor/bundle/bbb-html5-with-roles.conf
|
|
||||||
ExecStart=/usr/share/meteor/bundle/systemd_start.sh %i $BACKEND_NODEJS_ROLE
|
|
||||||
WorkingDirectory=/usr/share/meteor/bundle
|
|
||||||
StandardOutput=syslog
|
|
||||||
StandardError=syslog
|
|
||||||
TimeoutStartSec=10
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=10
|
|
||||||
User=meteor
|
|
||||||
Group=meteor
|
|
||||||
CPUSchedulingPolicy=fifo
|
|
||||||
Nice=18
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=bbb-html5.service
|
|
@ -1,29 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=BigBlueButton HTML5 service, frontend instance %i
|
|
||||||
Requires=bbb-html5.service
|
|
||||||
Before=bbb-html5.service
|
|
||||||
BindsTo=bbb-html5.service
|
|
||||||
StartLimitBurst=4
|
|
||||||
StartLimitInterval=70sec
|
|
||||||
StartLimitAction=none
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
PermissionsStartOnly=true
|
|
||||||
#Type=simple
|
|
||||||
Type=idle
|
|
||||||
EnvironmentFile=/usr/share/meteor/bundle/bbb-html5-with-roles.conf
|
|
||||||
ExecStart=/usr/share/meteor/bundle/systemd_start_frontend.sh %i
|
|
||||||
WorkingDirectory=/usr/share/meteor/bundle
|
|
||||||
StandardOutput=syslog
|
|
||||||
StandardError=syslog
|
|
||||||
TimeoutStartSec=10
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=10
|
|
||||||
User=meteor
|
|
||||||
Group=meteor
|
|
||||||
CPUSchedulingPolicy=fifo
|
|
||||||
Nice=18
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=bbb-html5.service
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
upstream poolhtml5servers {
|
|
||||||
zone poolhtml5servers 32k;
|
|
||||||
least_conn;
|
|
||||||
server 127.0.0.1:4100 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4101 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4102 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4103 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4104 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4105 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4106 fail_timeout=5s max_fails=3;
|
|
||||||
server 127.0.0.1:4107 fail_timeout=5s max_fails=3;
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
# Default = 2; Min = 1; Max = 4
|
|
||||||
# On powerful systems with high number of meetings you can set values up to 4 to accelerate handling of events
|
|
||||||
NUMBER_OF_BACKEND_NODEJS_PROCESSES=2
|
|
||||||
# Default = 2; Min = 0; Max = 8
|
|
||||||
# If 0 is set, bbb-html5 will handle both backend and frontend roles in one process (default until Feb 2021)
|
|
||||||
# Set a number between 1 and 4 times the value of NUMBER_OF_BACKEND_NODEJS_PROCESSES where higher number helps with meetings
|
|
||||||
# stretching the recommended number of users in BigBlueButton
|
|
||||||
NUMBER_OF_FRONTEND_NODEJS_PROCESSES=2
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
INSTANCE_MIN=1
|
|
||||||
INSTANCE_MAX=4
|
|
||||||
DESIRED_INSTANCE_COUNT=1
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
location @html5client {
|
location @html5client {
|
||||||
# proxy_pass http://127.0.0.1:4100; # use for development
|
proxy_pass http://127.0.0.1:4100;
|
||||||
proxy_pass http://poolhtml5servers; # use for production
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "Upgrade";
|
proxy_set_header Connection "Upgrade";
|
||||||
@ -15,13 +14,13 @@ location /html5client/__meteor__/dynamic-import/fetch {
|
|||||||
proxy_cache_lock on;
|
proxy_cache_lock on;
|
||||||
add_header X-Cached $upstream_cache_status;
|
add_header X-Cached $upstream_cache_status;
|
||||||
|
|
||||||
proxy_pass http://poolhtml5servers;
|
proxy_pass http://127.0.0.1:4100;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#location /html5client/join {
|
#location /html5client/join {
|
||||||
# alias /usr/share/meteor/bundle/programs/web.browser;
|
# alias /usr/share/meteor/bundle/programs/web.browser;
|
||||||
#}
|
#}
|
||||||
|
|
||||||
location /html5client/locales {
|
location /html5client/locales {
|
||||||
alias /usr/share/meteor/bundle/programs/web.browser/app/locales;
|
alias /usr/share/meteor/bundle/programs/web.browser/app/locales;
|
||||||
|
@ -5,16 +5,18 @@ After=redis-server.service mongod.service disable-transparent-huge-pages.service
|
|||||||
PartOf=bigbluebutton.target
|
PartOf=bigbluebutton.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=idle
|
||||||
ExecStart=/usr/share/meteor/bundle/workers-start.sh
|
ExecStart=/usr/share/meteor/bundle/workers-start.sh
|
||||||
WorkingDirectory=/usr/share/meteor
|
WorkingDirectory=/usr/share/meteor/bundle
|
||||||
# WorkingDirectory=/usr/share/meteor/bundle
|
StandardOutput=syslog
|
||||||
RemainAfterExit=yes
|
StandardError=syslog
|
||||||
# StandardOutput=syslog
|
TimeoutStartSec=10
|
||||||
# StandardError=syslog
|
Restart=on-failure
|
||||||
# User=meteor
|
RestartSec=10
|
||||||
# Group=meteor
|
User=meteor
|
||||||
User=root
|
Group=meteor
|
||||||
|
CPUSchedulingPolicy=fifo
|
||||||
|
Nice=18
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target bigbluebutton.target
|
WantedBy=multi-user.target bigbluebutton.target
|
||||||
|
@ -10,5 +10,19 @@ case "$1" in
|
|||||||
rm -r /usr/share/meteor/bundle/programs/server/node_modules
|
rm -r /usr/share/meteor/bundle/programs/server/node_modules
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Remove remnants from old architecture prior to BBB 3.0.x-alpha.6
|
||||||
|
if [ -f /usr/lib/systemd/system/bbb-html5-backend@.service ]; then
|
||||||
|
rm /usr/lib/systemd/system/bbb-html5-backend@.service
|
||||||
|
fi
|
||||||
|
if [ -f /usr/lib/systemd/system/bbb-html5-frontend@.service ]; then
|
||||||
|
rm /usr/lib/systemd/system/bbb-html5-frontend@.service
|
||||||
|
fi
|
||||||
|
if [ -f /etc/nginx/conf.d/bbb-html5-loadbalancer.conf ]; then
|
||||||
|
rm /etc/nginx/conf.d/bbb-html5-loadbalancer.conf
|
||||||
|
fi
|
||||||
|
if [ -f /etc/bigbluebutton/bbb-html5-with-roles.conf ]; then
|
||||||
|
echo "BigBlueButton 3.0+ does not support configurations in /etc/bigbluebutton/bbb-html5-with-roles.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -25,7 +25,6 @@ mkdir -p staging/usr/share/bigbluebutton/nginx
|
|||||||
cp bbb-html5.nginx staging/usr/share/bigbluebutton/nginx
|
cp bbb-html5.nginx staging/usr/share/bigbluebutton/nginx
|
||||||
|
|
||||||
mkdir -p staging/etc/nginx/conf.d
|
mkdir -p staging/etc/nginx/conf.d
|
||||||
cp bbb-html5-loadbalancer.conf staging/etc/nginx/conf.d
|
|
||||||
cp bbb-html5-conn-limit.conf staging/etc/nginx/conf.d
|
cp bbb-html5-conn-limit.conf staging/etc/nginx/conf.d
|
||||||
cp bbb-html5-meteor-assets-cache.conf staging/etc/nginx/conf.d
|
cp bbb-html5-meteor-assets-cache.conf staging/etc/nginx/conf.d
|
||||||
|
|
||||||
@ -78,17 +77,9 @@ if [ ! -f staging/usr/share/meteor/bundle/programs/web.browser/app/locales/index
|
|||||||
find staging/usr/share/meteor/bundle/programs/web.browser/app/locales -maxdepth 1 -type f -name "*.json" -exec basename {} \; | awk 'BEGIN{printf "["}{printf "\"%s\", ", $0}END{print "]"}' | sed 's/, ]/]/' > staging/usr/share/meteor/bundle/programs/web.browser/app/locales/index.json
|
find staging/usr/share/meteor/bundle/programs/web.browser/app/locales -maxdepth 1 -type f -name "*.json" -exec basename {} \; | awk 'BEGIN{printf "["}{printf "\"%s\", ", $0}END{print "]"}' | sed 's/, ]/]/' > staging/usr/share/meteor/bundle/programs/web.browser/app/locales/index.json
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp systemd_start.sh staging/usr/share/meteor/bundle
|
|
||||||
chmod +x staging/usr/share/meteor/bundle/systemd_start.sh
|
|
||||||
|
|
||||||
cp systemd_start_frontend.sh staging/usr/share/meteor/bundle
|
|
||||||
chmod +x staging/usr/share/meteor/bundle/systemd_start_frontend.sh
|
|
||||||
|
|
||||||
cp workers-start.sh staging/usr/share/meteor/bundle
|
cp workers-start.sh staging/usr/share/meteor/bundle
|
||||||
chmod +x staging/usr/share/meteor/bundle/workers-start.sh
|
chmod +x staging/usr/share/meteor/bundle/workers-start.sh
|
||||||
|
|
||||||
cp bbb-html5-with-roles.conf staging/usr/share/meteor/bundle
|
|
||||||
|
|
||||||
cp mongod_start_pre.sh staging/usr/share/meteor/bundle
|
cp mongod_start_pre.sh staging/usr/share/meteor/bundle
|
||||||
chmod +x staging/usr/share/meteor/bundle/mongod_start_pre.sh
|
chmod +x staging/usr/share/meteor/bundle/mongod_start_pre.sh
|
||||||
|
|
||||||
@ -99,10 +90,6 @@ mkdir -p staging/usr/lib/systemd/system
|
|||||||
cp bbb-html5.service staging/usr/lib/systemd/system
|
cp bbb-html5.service staging/usr/lib/systemd/system
|
||||||
cp disable-transparent-huge-pages.service staging/usr/lib/systemd/system
|
cp disable-transparent-huge-pages.service staging/usr/lib/systemd/system
|
||||||
|
|
||||||
cp bbb-html5-backend@.service staging/usr/lib/systemd/system
|
|
||||||
cp bbb-html5-frontend@.service staging/usr/lib/systemd/system
|
|
||||||
|
|
||||||
|
|
||||||
mkdir -p staging/usr/share
|
mkdir -p staging/usr/share
|
||||||
|
|
||||||
# replace v=VERSION with build number in head and css files
|
# replace v=VERSION with build number in head and css files
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
#Allow to run outside of directory
|
|
||||||
cd $(dirname $0)
|
|
||||||
|
|
||||||
if [ -z $1 ]
|
|
||||||
then
|
|
||||||
INSTANCE_ID=1
|
|
||||||
else
|
|
||||||
INSTANCE_ID=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
PORT=$(echo "3999+$INSTANCE_ID" | bc)
|
|
||||||
|
|
||||||
echo "instanceId = $INSTANCE_ID and port = $PORT and role is backend (in backend file)"
|
|
||||||
|
|
||||||
export INSTANCE_ID=$INSTANCE_ID
|
|
||||||
export BBB_HTML5_ROLE=backend
|
|
||||||
# this might be already set by a systemd unit override in case this node is run
|
|
||||||
# behind a load balancer proxy node
|
|
||||||
if [[ -z $ROOT_URL ]] ; then
|
|
||||||
export ROOT_URL=http://127.0.0.1/html5client
|
|
||||||
fi
|
|
||||||
export MONGO_OPLOG_URL=mongodb://127.0.1.1/local
|
|
||||||
export MONGO_URL=mongodb://127.0.1.1/meteor
|
|
||||||
export NODE_ENV=production
|
|
||||||
export SERVER_WEBSOCKET_COMPRESSION=0
|
|
||||||
export BIND_IP=127.0.0.1
|
|
||||||
PORT=$PORT /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js NODEJS_BACKEND_INSTANCE_ID=$INSTANCE_ID
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
#Allow to run outside of directory
|
|
||||||
cd $(dirname $0)
|
|
||||||
|
|
||||||
if [ -z $1 ]
|
|
||||||
then
|
|
||||||
INSTANCE_ID=1
|
|
||||||
else
|
|
||||||
INSTANCE_ID=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
PORT=$(echo "4099+$INSTANCE_ID" | bc)
|
|
||||||
|
|
||||||
echo "instanceId = $INSTANCE_ID and port = $PORT and role is frontend (in frontend file)"
|
|
||||||
|
|
||||||
export INSTANCE_ID=$INSTANCE_ID
|
|
||||||
export BBB_HTML5_ROLE=frontend
|
|
||||||
# this might be already set by a systemd unit override in case this node is run
|
|
||||||
# behind a load balancer proxy node
|
|
||||||
if [[ -z $ROOT_URL ]] ; then
|
|
||||||
export ROOT_URL=http://127.0.0.1/html5client
|
|
||||||
fi
|
|
||||||
export MONGO_OPLOG_URL=mongodb://127.0.1.1/local
|
|
||||||
export MONGO_URL=mongodb://127.0.1.1/meteor
|
|
||||||
export NODE_ENV=production
|
|
||||||
export SERVER_WEBSOCKET_COMPRESSION='{"level":5, "maxWindowBits":13, "memLevel":7, "requestMaxWindowBits":13}'
|
|
||||||
export BIND_IP=127.0.0.1
|
|
||||||
PORT=$PORT /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js
|
|
@ -23,37 +23,19 @@ done;
|
|||||||
|
|
||||||
echo "I'm the master!"
|
echo "I'm the master!"
|
||||||
|
|
||||||
|
#Allow to run outside of directory
|
||||||
|
cd $(dirname $0)
|
||||||
|
|
||||||
# Start parallel nodejs processes for bbb-html5. Number varies on restrictions file bbb-html5-with-roles.conf
|
PORT=4100
|
||||||
|
|
||||||
source /usr/share/meteor/bundle/bbb-html5-with-roles.conf
|
# this might be already set by a systemd unit override in case this node is run
|
||||||
|
# behind a load balancer proxy node
|
||||||
if [ -f /etc/bigbluebutton/bbb-html5-with-roles.conf ]; then
|
if [[ -z $ROOT_URL ]] ; then
|
||||||
source /etc/bigbluebutton/bbb-html5-with-roles.conf
|
export ROOT_URL=http://127.0.0.1/html5client
|
||||||
fi
|
fi
|
||||||
|
export MONGO_OPLOG_URL=mongodb://127.0.1.1/local
|
||||||
MIN_NUMBER_OF_BACKEND_PROCESSES=1
|
export MONGO_URL=mongodb://127.0.1.1/meteor
|
||||||
MAX_NUMBER_OF_BACKEND_PROCESSES=4
|
export NODE_ENV=production
|
||||||
|
export SERVER_WEBSOCKET_COMPRESSION='{"level":5, "maxWindowBits":13, "memLevel":7, "requestMaxWindowBits":13}'
|
||||||
MIN_NUMBER_OF_FRONTEND_PROCESSES=0 # 0 means each nodejs process handles both front and backend roles
|
export BIND_IP=127.0.0.1
|
||||||
MAX_NUMBER_OF_FRONTEND_PROCESSES=8
|
PORT=$PORT /usr/lib/bbb-html5/node/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js
|
||||||
|
|
||||||
|
|
||||||
# Start backend nodejs processes
|
|
||||||
if ((NUMBER_OF_BACKEND_NODEJS_PROCESSES >= MIN_NUMBER_OF_BACKEND_PROCESSES && NUMBER_OF_BACKEND_NODEJS_PROCESSES <= MAX_NUMBER_OF_BACKEND_PROCESSES)); then
|
|
||||||
for ((i = 1 ; i <= NUMBER_OF_BACKEND_NODEJS_PROCESSES ; i++)); do
|
|
||||||
systemctl start bbb-html5-backend@$i
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Start frontend nodejs processes
|
|
||||||
if ((NUMBER_OF_FRONTEND_NODEJS_PROCESSES >= MIN_NUMBER_OF_FRONTEND_PROCESSES && NUMBER_OF_FRONTEND_NODEJS_PROCESSES <= MAX_NUMBER_OF_FRONTEND_PROCESSES)); then
|
|
||||||
if ((NUMBER_OF_FRONTEND_NODEJS_PROCESSES == 0)); then
|
|
||||||
echo 'Need to modify bbb-html5.nginx to ensure backend IPs are used'
|
|
||||||
fi
|
|
||||||
for ((i = 1 ; i <= NUMBER_OF_FRONTEND_NODEJS_PROCESSES ; i++)); do
|
|
||||||
systemctl start bbb-html5-frontend@$i
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
@ -126,10 +126,9 @@ public:
|
|||||||
|
|
||||||
Create (or edit if it already exists) these unit file overrides:
|
Create (or edit if it already exists) these unit file overrides:
|
||||||
|
|
||||||
* `/usr/lib/systemd/system/bbb-html5-frontend@.service`
|
* `/usr/lib/systemd/system/bbb-html5.service`
|
||||||
* `/usr/lib/systemd/system/bbb-html5-backend@.service`
|
|
||||||
|
|
||||||
Each should have the following content:
|
It should have the following content:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Service]
|
[Service]
|
||||||
@ -137,14 +136,6 @@ Environment=ROOT_URL=https://127.0.0.1/bbb-01/html5client
|
|||||||
Environment=DDP_DEFAULT_CONNECTION_URL=https://bbb-01.example.com/bbb-01/html5client
|
Environment=DDP_DEFAULT_CONNECTION_URL=https://bbb-01.example.com/bbb-01/html5client
|
||||||
```
|
```
|
||||||
|
|
||||||
Change the nginx `$bbb_loadbalancer_node` variable to the name of the load
|
|
||||||
balancer node in `/usr/share/bigbluebutton/nginx/loadbalancer.nginx` to allow CORS
|
|
||||||
requests:
|
|
||||||
|
|
||||||
```
|
|
||||||
set $bbb_loadbalancer_node https://bbb-proxy.example.com;
|
|
||||||
```
|
|
||||||
|
|
||||||
Prepend the mount point of bbb-html5 in all location sections except for the
|
Prepend the mount point of bbb-html5 in all location sections except for the
|
||||||
`location @html5client` section in `/usr/share/bigbluebutton/nginx/bbb-html5.nginx`:
|
`location @html5client` section in `/usr/share/bigbluebutton/nginx/bbb-html5.nginx`:
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ Starting with BigBlueButton 2.3 many of the configuration files have local overr
|
|||||||
| /usr/share/bbb-apps-akka/conf/application.conf | /etc/bigbluebutton/bbb-apps-akka.conf | |
|
| /usr/share/bbb-apps-akka/conf/application.conf | /etc/bigbluebutton/bbb-apps-akka.conf | |
|
||||||
| /usr/share/bbb-fsesl-akka/conf/application.conf | /etc/bigbluebutton/bbb-fsesl-akka.conf | |
|
| /usr/share/bbb-fsesl-akka/conf/application.conf | /etc/bigbluebutton/bbb-fsesl-akka.conf | |
|
||||||
| /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml | /etc/bigbluebutton/bbb-html5.yml | Arrays are merged by replacement (as of 2.4-rc-5) |
|
| /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml | /etc/bigbluebutton/bbb-html5.yml | Arrays are merged by replacement (as of 2.4-rc-5) |
|
||||||
| /usr/share/meteor/bundle/bbb-html5-with-roles.conf | /etc/bigbluebutton/bbb-html5-with-roles.conf | |
|
|
||||||
| /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml | /etc/bigbluebutton/turn-stun-servers.xml | Replaces the original file |
|
| /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml | /etc/bigbluebutton/turn-stun-servers.xml | Replaces the original file |
|
||||||
| /usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml | /etc/bigbluebutton/bbb-webrtc-sfu/production.yml | Arrays are merged by replacement |
|
| /usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml | /etc/bigbluebutton/bbb-webrtc-sfu/production.yml | Arrays are merged by replacement |
|
||||||
| /usr/local/bigbluebutton/bbb-pads/config/settings.json | /etc/bigbluebutton/bbb-pads.json | Arrays are merged by replacement |
|
| /usr/local/bigbluebutton/bbb-pads/config/settings.json | /etc/bigbluebutton/bbb-pads.json | Arrays are merged by replacement |
|
||||||
@ -81,17 +80,15 @@ public:
|
|||||||
|
|
||||||
#### Log monitoring for server logs (bbb-html5)
|
#### Log monitoring for server logs (bbb-html5)
|
||||||
|
|
||||||
Since BigBlueButton 2.3 we run multiple nodejs processes in production mode, so tailing logs is slightly different from `journalctl -f bbb-html5.service` which was used in 2.2. Rather than listing all the services ( `bbb-html5-backend@1.service bbb-html5-backend@2.service bbb-html5-frontend@1.service bbb-html5-frontend@2.service bbb-html5-frontend@3.service bbb-html5-frontend@4.service ...` ) you can use the wildcard operator `*`. Notice the different process id for each bbb-html5-\* service. Also notice `systemd_start_frontend.sh` signifying a log from a frontend process vs `systemd_start.sh` - backend process.
|
In BigBlueButton 3.0 we modified the architecture to shift the load away from the old frontend and backend bbb-html5 pools of services. Logs for the new services can be foud via:
|
||||||
|
|
||||||
```
|
`journalctl -f -u bbb-html5.service`
|
||||||
# journalctl -f -u bbb-html5-*
|

|
||||||
-- Logs begin at Mon 2021-03-15 12:13:05 UTC. --
|
Akka-apps is responsible for most of the logic, so key info can be obtained via
|
||||||
Mar 15 15:14:18 demo2 systemd_start_frontend.sh[3881]: debug: Redis: SendCursorPositionEvtMsg completed sync
|

|
||||||
Mar 15 15:14:18 demo2 systemd_start_frontend.sh[3891]: debug: Redis: SendCursorPositionEvtMsg completed sync
|
`journalctl -f -u bbb-apps-akka.service`
|
||||||
Mar 15 15:14:18 demo2 systemd_start_frontend.sh[3888]: debug: Publishing Polls {"meetingId":"37d0fb4f4617b3c97948d717435f9e1cf6998477-1615821214341","userId":"w_el87iar97iwa"}
|
|
||||||
...
|
`SYSTEMD_LESS=FRXMK journalctl -u bbb-graphql-middleware.service -f` can also be useful.
|
||||||
Mar 15 15:30:18 demo2 systemd_start.sh[3869]: debug: Redis: UpdateBreakoutUsersEvtMsg completed sync
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Logs sent directly from the client
|
#### Logs sent directly from the client
|
||||||
|
|
||||||
|
@ -253,10 +253,6 @@ bbb-apps-akka ——————————————————————
|
|||||||
bbb-fsesl-akka ———————————————————————► [✔ - active]
|
bbb-fsesl-akka ———————————————————————► [✔ - active]
|
||||||
mongod ———————————————————————————————► [✔ - active]
|
mongod ———————————————————————————————► [✔ - active]
|
||||||
bbb-html5 ————————————————————————————► [✔ - active]
|
bbb-html5 ————————————————————————————► [✔ - active]
|
||||||
bbb-html5-backend@1 ——————————————————► [✔ - active]
|
|
||||||
bbb-html5-backend@2 ——————————————————► [✔ - active]
|
|
||||||
bbb-html5-frontend@1 —————————————————► [✔ - active]
|
|
||||||
bbb-html5-frontend@2 —————————————————► [✔ - active]
|
|
||||||
bbb-graphql-actions ——————————————————► [✔ - active]
|
bbb-graphql-actions ——————————————————► [✔ - active]
|
||||||
bbb-graphql-middleware ———————————————► [✔ - active]
|
bbb-graphql-middleware ———————————————► [✔ - active]
|
||||||
bbb-graphql-server ———————————————————► [✔ - active]
|
bbb-graphql-server ———————————————————► [✔ - active]
|
||||||
|
@ -48,7 +48,9 @@ Administrators will appreciate that we now allow passing of custom client settin
|
|||||||
#### Major strides in replacing Meteor
|
#### Major strides in replacing Meteor
|
||||||
|
|
||||||
For years we have discussed internally the topic of replacing MeteorJS with other technologies in order to improve scalability, performance, etc. In the last year we have introduced several different new components which are to replace Meteor. The work is underway, it will span into BigBlueButton 3.0, 3.1, possibly 3.2 too.
|
For years we have discussed internally the topic of replacing MeteorJS with other technologies in order to improve scalability, performance, etc. In the last year we have introduced several different new components which are to replace Meteor. The work is underway, it will span into BigBlueButton 3.0, 3.1, possibly 3.2 too.
|
||||||
These new components are: `bbb-graphql-server`, `bbb-graphql-middleware`, `bbb-graphql-actions`, database Postgres, GraphQL server Hasura. During the transition period, `bbb-html5-backend` and `bbb-html5-frontend` are still present, however, lots of what they used to do is now being carried out by the new components.
|
These new components are: `bbb-graphql-server`, `bbb-graphql-middleware`, `bbb-graphql-actions`, database Postgres, GraphQL server Hasura.
|
||||||
|
|
||||||
|
Note: The services `bbb-html5-backend` and `bbb-html5-frontend` have been removed and `bbb-html5` modified heavily as a result of the change in architecture.
|
||||||
|
|
||||||
### Experimental
|
### Experimental
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user