Understanding Microsoft Teams Live Share SDK and how to use it
At Microsoft Ignite 2022, the Microsoft Teams team announced Live Share SDK as a new way to “transform Teams apps into collaborative multi-user experiences without writing any dedicated back-end code”.
The demo showed a polished in-meeting app demo from partner Hexagon with meeting participants collaborating on a cut-away engineering drawing:
So, what is that exciting new SDK and how can it be used by Teams developers everywhere to create experiences as collaborative as this?
In this post, I’m going to try to explain exactly what got announced, but also the component pieces underlying the new technology so that you will have a better understanding of what’s possible, and how best to use it.
Let’s start with Fluid Framework
“a collection of client libraries for distributing and synchronizing shared state. These libraries allow multiple clients to simultaneously create and operate on shared data structures using coding patterns similar to those used to work with local data”
If you’ve ever tried to manage shared state, at scale and with low latency, you’ll know it’s not easy. This is what Fluid Framework is trying to solve.
It works by giving you nicely-abstracted client libraries to a range of their own data structures, each of which maps to a different sort of data you might want to store. Names like “SharedString”, “SharedCounter”, “SharedMap” give you a sense. The libraries then let you get and set these values in your front-end code without worrying much about how they are stored and synchronised. Set it in one client, and it’s instantly available in all other clients.
So.. it’s SignalR?
This was my initial question. At first glance, Fluid Framework sounded like it was solving the same problem as SignalR. However, that’s not quite true. SignalR is for sending messages. Fluid Framework is for maintaining state.
There’s a great SO answer on this, that gives a good example:
How would a last write wins algorithm [such as you might implement using SignalR] handle two users simultaneously editing a string?
- Starting state “Hello World”
- Alice adds “!” at the end
- Bob adds “?” at the end
You might have odd behavior resulting in “Hello World?” or “Hello World!”.
Fluid orders Bob’s change and Alice’s change through the Fluid service. The merge tree data structure then has a reproducible merge algorithm for applying those ordered changes. Ultimately the string would read “Hello World?!”
This is a simple example, but in the real-world the objects and relationships might be a lot of complicated, especially when it comes to synchronizing visual state.
Let’s do a quick demo. I’ve picked this demo because it’s REALLY simple to get started. Do the demo, and then come back with your questions – I think I know what they might be, and I’ll answer them.
The demo is a DiceRoller application, which you can follow here: Tutorial: DiceRoller application (fluidframework.com)
In the demo you’ll create a simple webpage running locally. With two browser windows open, state from one window is automatically reflected in the other window.
If you followed along, and got the demo working, then you might be kinda impressed … but also kinda not.
The demo was all working locally. We didn’t create anything in Azure. So, what is actually synching these states up, and how does it work out in the real world? It all looks good on localhost, but with a suspicion it won’t work anywhere else…
The answer is that there are multiple different implementations of the Fluid Framework, and the demo is using one of these: a Fluid service called Tinylicious which is meant to be run locally for development. If you look through the output of the npm start function you’ll probably see some references to it.
Fluid Framework, then, is:
- a collection of client libraries to let your code work with data types that Fluid can use, AND
- a service that is capable of taking those data types and magically keep them synched up.
Fluid Framework in the real world
As you might have guessed, although it’s super useful, Tinylicious isn’t the thing we want to go to production running our Fluid components on (and not just because of the name). What’s really needed is the same sort of service, but implemented in the cloud at scale.
Enter Azure Fluid Relay. Azure Fluid Relay takes up where Tinylicious leaves off, and give you a managed Fluid service you can use to manage state for your application, running in Azure.
Conceptually, it would be possible to take the DiceRoll application and swap out Tinylicious for Azure Fluid Relay without making any changes to the rest of the code. If you wanted to roll dice with someone on the other side of the world in real-time.
How do I use Fluid Framework?
Fluid Framework is a way of managing state across multiple clients. Nothing more, nothing less.
If what you’re planning on building relies on having a text box which multiple people can edit in real-time, you can see how you could tie this to a SharedString and have Fluid Framework manage keeping it all in sync.
But, if you’re planning something much grander, with multiple cursors on the screen and edit comments popping up here and there in lots of different colours (think the Loop intro video), that is going to involve a lot more work. Not more work in keeping state synchronized, just more visual and front-end work. Fluid Framework doesn’t short-cut any of the visual UI work needed to create a great experience.
What does any of this have to do with Live Share SDK?
Bear with me, because this whole post has been building to this mic-drop moment.
There’s now another type of Fluid service, to complement Tinylicious and Azure Fluid Relay, which developers can use in the same way.
This new service (the Live Share service) is automatically created for every Microsoft Teams meeting, and is free for developers to use (no Azure Relay to set up and configure, no additional Azure charges, will “just work” with the SDK).
For developers building meeting apps in Teams, this means that they can use Fluid Framework to synchronise state, but without having to worry about:
- sharding data in a shared Azure Fluid Relay instance to ensure data from one meeting doesn’t end up synching into another meeting
- the cost of running Azure Fluid Relay
- tidying up after the meeting ends (Live Share instances are automatically destroyed 24 hours after the meeting starts)
If you’re already using Fluid Framework to synchronize state in your in-meeting applications, moving to Live Share is probably something of a no-brainer just for the cost savings … UNLESS you need that state to persist and not be destroyed when the meeting finishes.
But wait, there’s more!
On top of this, I think I’m correct in saying that there are some classes which are unique to the Live Share service. These are focused on synchronizing media: such as the playback of audio and video files, and will wrap around a <video> object to provide a synchronization layer to controls.
This would allow for direct collaboration on a video: so that when one person pauses, it pauses for all. There are a number of clever additions to this as well, such as temporary suspensions and co-ordination points. Example: if a group is watching a video, then individuals can pause and resume playback without impacting others, but the whole group have to wait until everyone has watched the whole video before proceeding.
Current Limitations and Gotchas
- Data stored in Live Share is deleted after 24 hours,
- Currently, only scheduled meetings are supported, and all participants must be on the meeting calendar,
- Meeting types such as, one-on-one calls, group calls, and meet now are currently not supported,
- Max 100 clients per session (so, 100 attendees in a meeting),
- the media synchronization stuff doesn’t work with DRM-encrypted content.
If you’re already working with a shared state and synchronizing up changes for in-meeting apps in Teams then I think you will benefit from looking at Live Share as a way to simplify your solution and reduce the amount of code you are responsible for.
If you haven’t yet added features to your in-meeting app because it would require coordination and synchronization and that all seemed quite hard: this is your savior.
Just be aware though, this isn’t a complete silver bullet. You are still responsible for visually representing all the things that are happening. Live Share brings you a shared object model you can rely on during a Teams meeting, but don’t underestimate the effort needed to apply this model in the UI layer.