Merge pull request #5064 from GabrielInTheWorld/doubleHitProjector
Enhances the autoupdate of projector by change-id
This commit is contained in:
commit
50bd31a9a6
@ -18,6 +18,21 @@ interface AllProjectorData {
|
||||
[id: number]: ProjectorData | { error: string };
|
||||
}
|
||||
|
||||
/**
|
||||
* Received data from server.
|
||||
*/
|
||||
interface ProjectorWebsocketMessage {
|
||||
/**
|
||||
* The `change_id` of the current update.
|
||||
*/
|
||||
change_id: number;
|
||||
|
||||
/**
|
||||
* The necessary new projector-data.
|
||||
*/
|
||||
data: AllProjectorData;
|
||||
}
|
||||
|
||||
/**
|
||||
* This service handles the websocket connection for the projector data.
|
||||
* Each projector instance registers itself by calling `getProjectorObservable`.
|
||||
@ -43,6 +58,11 @@ export class ProjectorDataService {
|
||||
*/
|
||||
private readonly updateProjectorDataDebounceSubject = new Subject<void>();
|
||||
|
||||
/**
|
||||
* Holds the current change id to check, if the update contains new content or a deprecated one.
|
||||
*/
|
||||
private currentChangeId = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@ -50,13 +70,17 @@ export class ProjectorDataService {
|
||||
*/
|
||||
public constructor(private websocketService: WebsocketService) {
|
||||
// Dispatch projector data.
|
||||
this.websocketService.getOberservable('projector').subscribe((update: AllProjectorData) => {
|
||||
Object.keys(update).forEach(_id => {
|
||||
this.websocketService.getOberservable('projector').subscribe((update: ProjectorWebsocketMessage) => {
|
||||
if (this.currentChangeId > update.change_id) {
|
||||
return;
|
||||
}
|
||||
Object.keys(update.data).forEach(_id => {
|
||||
const id = parseInt(_id, 10);
|
||||
if (this.currentProjectorData[id]) {
|
||||
this.currentProjectorData[id].next(update[id] as ProjectorData);
|
||||
this.currentProjectorData[id].next(update.data[id] as ProjectorData);
|
||||
}
|
||||
});
|
||||
this.currentChangeId = update.change_id;
|
||||
});
|
||||
|
||||
// The service need to re-register, if the websocket connection was lost.
|
||||
|
@ -179,9 +179,7 @@ class ListenToProjectors(BaseWebsocketClientMessage):
|
||||
for projector_id, data in projector_data.items():
|
||||
consumer.projector_hash[projector_id] = hash(str(data))
|
||||
|
||||
await consumer.send_json(
|
||||
type="projector", content=projector_data, in_response=id
|
||||
)
|
||||
await consumer.send_projector_data(projector_data, in_response=id)
|
||||
|
||||
|
||||
class PingPong(BaseWebsocketClientMessage):
|
||||
|
@ -217,7 +217,12 @@ def handle_changed_elements(elements: Iterable[Element]) -> None:
|
||||
# Send projector
|
||||
channel_layer = get_channel_layer()
|
||||
await channel_layer.group_send(
|
||||
"projector", {"type": "projector_changed", "data": projector_data}
|
||||
"projector",
|
||||
{
|
||||
"type": "projector_changed",
|
||||
"data": projector_data,
|
||||
"change_id": change_id,
|
||||
},
|
||||
)
|
||||
|
||||
if elements:
|
||||
|
@ -190,6 +190,8 @@ class SiteConsumer(ProtocollAsyncJsonWebsocketConsumer):
|
||||
The projector has changed.
|
||||
"""
|
||||
all_projector_data = event["data"]
|
||||
change_id = event["change_id"]
|
||||
|
||||
projector_data: Dict[int, Dict[str, Any]] = {}
|
||||
for projector_id in self.listen_projector_ids:
|
||||
data = all_projector_data.get(projector_id, [])
|
||||
@ -199,4 +201,19 @@ class SiteConsumer(ProtocollAsyncJsonWebsocketConsumer):
|
||||
self.projector_hash[projector_id] = new_hash
|
||||
|
||||
if projector_data:
|
||||
await self.send_json(type="projector", content=projector_data)
|
||||
await self.send_projector_data(projector_data, change_id=change_id)
|
||||
|
||||
async def send_projector_data(
|
||||
self,
|
||||
data: Dict[int, Dict[str, Any]],
|
||||
change_id: Optional[int] = None,
|
||||
in_response: Optional[str] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Sends projector data to the consumer.
|
||||
"""
|
||||
if change_id is None:
|
||||
change_id = await element_cache.get_current_change_id()
|
||||
|
||||
content = {"change_id": change_id, "data": data}
|
||||
await self.send_json(type="projector", content=content, in_response=in_response)
|
||||
|
@ -565,12 +565,15 @@ async def test_listen_to_projector(communicator, set_config):
|
||||
content = response.get("content")
|
||||
assert type == "projector"
|
||||
assert content == {
|
||||
"change_id": 3,
|
||||
"data": {
|
||||
"1": [
|
||||
{
|
||||
"data": {"name": "slide1", "event_name": "OpenSlides"},
|
||||
"element": {"id": 1, "name": "test/slide1"},
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -595,12 +598,15 @@ async def test_update_projector(communicator, set_config):
|
||||
content = response.get("content")
|
||||
assert type == "projector"
|
||||
assert content == {
|
||||
"change_id": 4,
|
||||
"data": {
|
||||
"1": [
|
||||
{
|
||||
"data": {"name": "slide1", "event_name": "Test Event"},
|
||||
"element": {"id": 1, "name": "test/slide1"},
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user