Comments (8)
Hey @nmtoblum, yeah this is great feedback, thank you for being so thorough! We have some work to do in this area for sure. While we are formally releasing @microsoft/live-share, -media, and -canvas to v1.0.0 at Build in a couple weeks, the React & Turbo packages will stay in Preview. So we're still working some of this out, but I will make a note to ensure that the error messages be more consistent across these three paradigms.
What you are touching on here relates to how Fluid Framework works. Basically, anything that is in initialObjects
from your ContainerSchema
is created before the IFluidContainer
is created, and currently they don't support changing those initialObjects
after the container is created.
So I asked myself how this situation could be handled in Teams where maybe more then one live-share-* app is started in the same meeting. The first will win? But how should the second app handle this?
These containers are stored in our server for about 6 hours after you first install the app to a meeting, before we delete them. Each unique application in Teams gets one container per meeting, meaning that apps do not get access to any other container you have already created.
This is determined by two things, which we do primarily for security reasons and to avoid the issue which you mentioned above:
- Your application's unique
id
, as determined in your app manifest - The origin URL of your application
That means that even if an app has the same identifier as you, if your origin is different then you will have two separate containers for a single meeting. You won't have any conflicts with other Teams apps, just your own while you are testing a different app schema within the same 6 hour window.
This gives you two ways to "reset" your container while you're still flushing out your app & schema:
- Simply create a new meeting and sideload it there. Meet Now meetings are the easiest way for this, generally.
- Change one character of your "id" in your app manifest and reinstall. Obviously you want a static app ID for your production app, but there is nothing stopping you from changing it as many times as you'd like during development. Usually we just do a new meeting though, since zipping the manifest and uploading the new app package is a bit clunky.
RE: other stuff mentioned
Containers created by LiveShareTurboClient
(and consequentially live-share-react) are not compatible with that from the regular LiveShareClient
. This is because Live Share Turbo actually abstracts away the schema so you don't have this issue. LiveShareTurboClient
uses a single initialObjects
entry called DynamicObjectsManager
, which is what you're seeing in that first error message. It is the same as if you did this in the Live Share client:
import { LiveShareClient, TestLiveShareHost } from "@microsoft/live-share";
import { DynamicObjectsManager } from "@microsoft/live-share-turbo";
const schema = {
initialObjects: {
TURBO_STATE_MAP: DynamicObjectsManager,
},
dynamicObjectTypes: [...every DDS possible in your app],
}
We might change this in a future update -- we are talking with the Fluid Framework team about how we could create the TURBO_STATE_MAP
without depending on initialObjects
at all (effectively doing what they do under the hood w/ initialObjects, rather than adding an additional abstraction). However, it does mean that you can get some portability between live-share-react
and live-share-turbo
, as long as you are using the same keys for each DDS.
For example, if you use this in React:
import { useLiveState } from "@microsoft/live-share-react";
const FOO_KEY= "foo";
export const SomeComponent = () => {
const [foo, setFoo] = useLiveState<string>(FOO_KEY, "bar");
return (
<div>
{foo}
</div>
);
}
That is the same as this in live-share-turbo
:
import { LiveShareTurboClient } from "@microsoft/live-share-turbo";
import { LiveState, TestLiveShareHost } from "@microsoft/live-share";
const FOO_KEY= "foo";
const host = TestLiveShareHost.create();
const client = new LiveShareTurboClient(host);
await client.join();
const fooState = await client.getDDS(FOO_KEY, LiveState);
fooState.on("stateChanged", (latest) => {
// update app
});
await fooState.initialize("bar");
Technically you could make the LiveShareClient
work with Turbo client as well, if you were really motivated, though at that point you might as well just use LiveShareTurboClient
.
Hope this helps! Happy to answer more questions, and definitely keep sharing candid feedback, it's super helpful!
from live-share-sdk.
One thing I wanted to add: To get a better understanding what happens here and to reduce complexity, I took another step back and tried to implement a similar minimal solution with live-share-turbo. It's in this branch: https://github.com/toblum/spotalot/tree/live-share-turbo
When running this code I always get this error message:
This happens every time when this line is executed: https://github.com/toblum/spotalot/blob/c95e8e6de9b6c2ce7a5382711f186703ee98e8d7/client/src/pages/SidePanel.tsx#L19
I think that could be related as I saw this error also when using live-share-react.
Greetings
Tobias
from live-share-sdk.
And I even went back one more step and tried the same as vanilla live-share:
https://github.com/toblum/spotalot/tree/minimal
Here I always get the error: Error: Registry does not contain entry for the package
Now I'm at the end of my rope. I have no idea what I did wrong here.
Would be great if you could give me a hint what's happening here.
Greetings
Tobias
from live-share-sdk.
Hey @nmtoblum, thanks for reporting this! Thanks for linking to your test project, I will see if I can repro on my machine and get back to you ASAP.
from live-share-sdk.
One thing I noticed, which we have done a poor job at documenting...@fluidframework/azure-client
version 1.1 or greater have an issue right now because of a breaking change they introduced that we only recently caught. If you are testing in Teams, that would probably line up with the AzureUser issue you were seeing.
We have a server-side patch coming next week, but in the meantime if you change the @fluidframework/azure-client
version to "~1.0.2" that should at least fix that issue.
As for this one:
And I even went back one more step and tried the same as vanilla live-share:
https://github.com/toblum/spotalot/tree/minimalHere I always get the error: Error: Registry does not contain entry for the package
This is probably because you were testing in the same meeting as before. This is something Live Share Turbo / React are meant to help. Because the container was created using the Live Share Turbo structure, that means the schema you defined for the base client mismatched that of what is used in Turbo/React. The base Live Share package doesn't yet support migrating schema, but to fix you can just create a new meeting and test from there.
Let me know if this helps!
from live-share-sdk.
Also this isn't the issue, but I noticed the following:
const { created } = useLiveShareContext();
const host = TestLiveShareHost.create();
return (
<div>
SidePanel
<LiveShareProvider joinOnLoad host={host}>
LSP
{created}
<GameSettings></GameSettings>
</LiveShareProvider>
</div>
);
First issue, useLiveShareContext();
should only be accessed from within a child component. I would nest another component within SidePanel.tsx
, because otherwise that will always be undefined. Also, created
is referring to whether the local user was the one to create the container.
The second is regarding the host
. Generally, you should either wrap those in a useState
or even define it outside of the component. This will ensure it doesn't re-create the object on every render.
I would recommend something closer to the following:
import { LiveShareProvider, useFluidObjectsContext } from "@microsoft/live-share-react";
import { LiveShareHost } from "@microsoft/live-share";
import { useState } from "react";
const SidePanel = () => {
// teams-js must be initialize before LiveShareHost.create() will work
const [host] = useState(LiveShareHost.create());
return (
<LiveShareProvider host={host} joinOnLoad>
<SidePanelRenderer />
</LiveShareProvider>
)
}
const SidePanelRenderer = () => {
const { container } = useFluidObjectsContext();
if (!container) return (<Spinner />);
return (<GameSettings />);
}
from live-share-sdk.
Hi Ryan,
thanks for your quick reply and for taking the time to investigate my problem.
The note about the version of @fluidframework/azure-client
was spot on. That solved a lot of things already:
- minimal: The error
Registry does not contain entry for the package
is gone and I think I could build a vanilla live-share solution now. I have not tested further yet. - live-share-turbo: This solution works now too.
- live-share-react: With your code example it works now too. I probably oversimplified the code a bit during my tests. :-)
At first, however, no variant worked and the error messages were confusing, but I drilled a little deeper and I think I understood why my tests over the last few days gave such confusing results:
I always tested in teams meetings. Today, I tested the "minimal" example first and tried it successfully (that registered an exampleMap in the Fluid container). Then I tried the live-share-turbo solution in the same meeting. That then failed with an error message that looked like this:
Then I tried live-share-react example and got this error message:
I made sure that the container exists before, so I couldn't explain why it's undefined. After logging the container I saw it:
container is available, initial objects: {exampleMap: SharedMap}
The container already existed in the meeting (with the exampleMap from the minimal example I started earlier). So the live-share-turbo client in live-share-react took this existing container, but could not create it's internal TURBO_STATE_MAP object, but assumes that it's already there then breaks with the error above.
So I asked myself how this situation could be handled in Teams where maybe more then one live-share-* app is started in the same meeting. The first will win? But how should the second app handle this?
It would be nice if you could give me some guidance on this. Many thanks in advance for your support.
Many greetings
Tobias
from live-share-sdk.
Hello Ryan,
thank you for all the information. It all helps me a lot to understand how it works. I'm also glad to hear that (vanilla) live-share will be 1.0 soon. Then with that we can build solutions that can be used productively later on.
Thanks also for the information on how new containers are created. If a new container is created per application ID and meeting, then no problems are to be expected and the observed irregularities can only be attributed to my unsuitable development setup. Now I simply create a new meeting more often. That makes it less complicated.
Otherwise, as soon as possible, I will just work a bit more with live-share(-react) and also onboard my colleagues. I have a few ideas for apps. If I run into any problems or questions along the way, I won't hesitate to post them again. Thanks again for the super helpful support.
Many greetings
Tobias
from live-share-sdk.
Related Issues (20)
- [JS Bug]: Presence updates not emitted after PresenceState expires
- [Feature Request]: Disable sending position updates in viewOnly mode HOT 1
- [JS Bug]: <insert title here>
- [Bug]: <insert title here> HOT 2
- [Feature Request]: can send position updates setting for media package
- [Task]: Clean up Dependabot PR's
- meeting.getAppContentStageSharingState() does not trigger callback on iOS HOT 2
- [Bug]: Presence object does not have localUser object HOT 3
- presenceChanged callback not getting called on Android Teams app. HOT 9
- Live Share not working HOT 2
- Unable to add Live Canvas sample to teams tabs HOT 3
- Role Vertification of LiveCanvas not working HOT 5
- [Feature Request]: Setting to prevent sending background events in object synchronizer
- [Feature Request]: Expose clientId in ExtendedMediaSessionActionDetails
- [Feature Request]: Access optimized `getClientInfo()` API without using `LivePresence`
- [Feature Request]: Setting for LiveCanvas to prevent local user from sending signals / making ops
- [Bug][LiveCanvas]: Laser Pointer and highlighter first and last position persists for non local clients
- [Feature Request]: Add local flag to `ExtendedMediaSessionDetails` for groupaction
- [JS Bug]: Event listener breaks video pause function HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from live-share-sdk.