-
Notifications
You must be signed in to change notification settings - Fork 282
add websocket servers for amcp and monitor data #1654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I think this is very use full. What changes does it send. does it send continuous data like audio levels and clip position? if so may be a 3rd socket is needed as for some applications you only need layer states and not the potential loud data. But always better then the bulky / loud OSC that we have now. |
I haven't read the code or thought about this much yet, but a couple of ideas: Perhaps this should operate in a way of letting the client say what they want to listen to (and perhaps potentially the format of the data?) And while I like that this is using json-patch, I wonder if that might be frustrating for some uses because of the extra complexity needed (while this works well for something like js, I dont know how well supported it is in other languages). so it would be nice to be able to specify this, perhaps as part of some 'subscribe' calls the client makes. json-patch can be the default though. |
@MauriceVeraart currently the full state of the server (all OSC paths) is sent upon connection then an update is sent per frame with any change deltas. @Julusian I do believe we need a subscription system for the monitor connections although currently the JSON patch implementation really cuts down on bandwidth. The one thing I like immensely about the JSON patch mechanism is that we can now know exactly when a stage goes empty because we’ll get a remove op for that path. That has been the most awkward part of the OSC system for me. JSON patch seems to have decent community support in most languages. OSC is awkward enough, I’m not sure we need to worry about taking a stance on sending change deltas in a specified format. There is RFC 7386 JSON Merge Patch that might be less awkward and still provide the same removal functionality. I will look into that. I will work on implementing a wildcard enabled path subscription system with a default subscription configurable on the server. We’ll give the user control over these options…but the big question is what will the defaults look like? Do we send nothing and require subscription command/s for paths we are interested in? Do we always send full state of all subscribed paths on every frame or send full state then subsequent change deltas? |
…detect path removal
I've now switched the change deltas to come as RFC7386 format which are less awkward to clients. The user can implement their own merge strategy quite easily in their language if it is not supported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Though I think the patching is not strictly necessary. It's not so much data. Why not just always send the whole state and the server diff and apply changes?
I think you need to explicitly subscribe to paths + some kind of wildcard + update interval, e.g. |
Another thing. Add a server timestamp to every update. |
Good point. I’m thinking browser or even template clients that might get
overwhelmed with 50-60fps full state. Especially if the server has many
channels, etc. I do like the idea of subscribing to interesting paths.
The diffing mechanism would be unneeded at that point. I will keep
iterating on this.
…On Wed, Jul 9, 2025 at 08:18 Robert Nagy ***@***.***> wrote:
***@***.**** approved this pull request.
LGTM
Though I think the patching is unecessary. It's not so much data. Why not
just always send the whole state and the server diff and apply changes?
—
Reply to this email directly, view it on GitHub
<#1654 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAWT6IJLFLXQR2C4FEECPIT3HUCAFAVCNFSM6AAAAACAZOFYYKVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTAMBRGMYTQNRWGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
…ion after sustained failures (30s)
Path based subscriptions implemented. See PR description. |
This isn't ready, there are performance issues. Marking as draft for now. |
@TomKaltz just curious, is there a problem with using OSC? |
@dimitry-ishenko I've used OSC very reliably for many years with great success but there were things that always bothered me. One big issue I have is that you can't immediately definitively know when a stage is empty/cleared since that stage will just stop producing OSC messages. This required awkward checks with timeouts to detect when a stage/layer stopped producing data. With this implementation, as long as you aren't using a wildcard for the layer subscriptions, the layer will transmit The advantages I see to adding websockets are as follows...
I'm hoping hoping this PR will add value to CasparCG Server. I always suspected it would. I will be testing it heavily with a client project I'm working on right now so I hope to get it as bullet-proof as possible ASAP. |
Hi @TomKaltz, First of all, thank you for your work on this pull request! I have a question regarding the scope of the information that will be exposed via this new WebSocket. Beyond general server status, would it be possible to include more granular internal state information for individual layer? Specifically, I'm referring to states such as:
Currently, when developing clients that interact with CasparCG, determining the precise state of a clip using OSC is quite challenging. We often have to infer a clip's state through a combination of its name, time, and duration, and then manage multiple conditional checks on the client-side. This approach is prone to inaccuracies and adds significant complexity to client development. This is especially problematic when replaying the same clip or play another clip on same layer, as the server often initially sends outdated time and duration information for a brief period before providing the actual, current details of the clip. Exposing explicit clip states via the WebSocket would greatly simplify client-side logic and enable more robust and responsive UIs. It would eliminate the need for clients to "guess" the state and instead allow them to react directly to definitive state changes from the server. Is this something that you've considered, or do you think it would be feasible to incorporate into this WebSocket implementation? Thanks again for your efforts! |
@sirfnomi this PR IMHO starts the journey toward less awkward realtime state. Though, given how the core of CasparCG server is architected, it's not entirely trivial to generically derive and distribute exact playback state for producers in the system. Please open another issue to start a discussion about a better semantic for playback/layer statuses. |
Also @sirfnomi currently the websocket implementation has access to any path/value that is currently being output to OSC. The idea though is to add more diagnostic information to the status monitor system and to move away from the old DIAG window. We'll have to think carefully about this because currently all paths are output to OSC without filtering so we might not be able to add too much unless we add filtering capability to the OSC broadcasts. It will be an ongoing disucssion as we migrate to more modern realtime status mechanism. |
That makes perfect sense, and I appreciate your candid explanation regarding the architectural challenges. I completely understand if this specific feature isn't trivial to integrate into the system. |
WIP FEEDBACK NEEDED
implement websocket server using boost beast for AMCP and monitoring with RFC7386 JSON MERGE PATCH change deltas.
Exposes 2 websocket ports…One for AMCP(5251)…the other port for monitoring(5252). When a client connects to the monitor websocket, a welcome message is sent to the client...
When you first connect, you'll receive a welcome message with instructions:
after the client sends the subscribe command payload they should receive a confirmation then the filtered subscribed data will start streaming at the fastest channel fps. Please note that a subscribe command is NOT additive. It will overwrite the previous subscription include and exclude arrays on the server.
Streaming data comes with message type filtered_state.
The client can request a full_state message by sending
{“command”:”request_full_state”}
then a one-time message of typefull_state
will be sent with all unfiltered server monitor data.Note: This PR will not implement WSS so standard web browsers will NOT allow a non-secure websocket connection to the server across a network. Browsers can still connect if the CasparCG Servver is on localhost. This allows the use case of an [html] template connecting to the websocket server over websockets for control and/or realtime status data.