Sharing with Orkestra - WEKIT-ECS/MIRAGE-XR GitHub Wiki
Example of a scene with Orkestra implementation inside MirageXR
The scene using orkestra can be found at:
/OrkestraLib/Example/OrkestraScene.unity
This scene includes the ExampleOrkestra.cs script which includes a simple example using Orkestra and can be found at:
/OrkestraLib/Example/ExampleOrkestra.cs
This example creates the connection with the Orkestra Server and registers all the necessary messages and events to be able to send messages to a specific user or to all the users connected to the same session.
The most important steps are the following:
Connection with Orkestra
- Subscribe to the user channel: The user event channel is used when a message is sent to a specific user. The subscriber allows to recibe messages though that channel.
- Subscribe to the application channel: The application event channel is used when a message is sent in a broadcast way, to all the users connected to the same session. The subscriber allows to recibe messages though that channel.
- Register the type of message that the app would manage: Orkestra allows to define different structures to be shared as messages. Those messages have to be registered.
- Install the socket library: H.Socket.IO library is the one that works best.
- Create the connection with the server: The Connect method establishes the connection with Orkestra Server. In order to do that, three parameters are needed. The room, which is the name of the session to the one the users are going to be connected. The agentId, which is the user ID. And the url, which is the url where the server is hosted (https://cloud.flexcontrol.net). In the example these three parameters are inherited from the Orkestra class in Orkestra.cs script. However, they can be configured through the unity interface when the ExampleOrkestra.cs script is included in the scene.
/OrkestraLib/Example/ExampleOrkestra.cs
void Start(){
//Register the callback that receives the events from the user event channel
UserEvents += UserEventSubscriber;
//Register the callback that receives the events from the app event channel
ApplicationEvents += AppEventSubscriber;
// Register custom messages to be used in the app
RegisterEvents(new Type[]{
typeof(ExampleOrkestraMessage),
});
//Installation of H.Socket.IO library
OrkestraWithHSIO.Install(this, (graceful, message) =>
{
Events.Add(() =>
{
if (!graceful)
{
Debug.Log(graceful);
}
else
{
Debug.LogError("Error: "+message);
}
});
});
try
{
// Start Orkestra
Connect(() =>
{
Debug.Log("All stuff is ready");
});
}
catch (ServiceException e)
{
Debug.LogError(e.Message);
}
}
Sending information
As mentioned before, there are two options to share information. In both cases Dispatch method is used, specifying the channel to use.
- Send info to a specific user: Channel.User is specified as the first argument of the Dispatch Method. Apart from that, the message and the target user ID have to be included.
- Send info to all the users connected to the same session: Channel.Application is specified as the first argument of the Dispatch Method. Apart from that, the message has to be included.
It is important to note that the Users variable, inherited from the Orkestra class, contains the information of all the users connected to the same session.
/OrkestraLib/Example/ExampleOrkestra.cs
// Method to send a message to a specific user
public void SendUserMessage()
{
//In this case we send a message to every user except to itself
//Users contains the information from all the connected users
//Users.Keys will return all the agentIds
foreach(string userid in Users.Keys)
if(userid!=agentId)
Dispatch(Channel.User, new ExampleOrkestraMessage(this.agentId, messageInput.text),userid);
}
//Method to send a broadcast message
public void SendAppMessage()
{
Dispatch(Channel.Application, new ExampleOrkestraMessage(this.agentId, messageInput.text));
}
Subscribing to the user and application channels
The two callbacks registered at the begining have to be implemented so that the app receives the events sent by other users:
- UserEventSubscriber: receives messages from the user channel.
- AppEventSubscriber: receives messages from the application channel.
/OrkestraLib/Example/ExampleOrkestra.cs
//callback that receives the messages from the user channel
void UserEventSubscriber(object orkestraLib, UserEvent evt)
{
if (evt.IsPresenceEvent())
{
// Start session only when user is logged in
if (evt.IsUser(agentId) && evt.IsJoinEvent())
{
Debug.Log("Logged as '" + evt.agentid + "' ");
}
}
else if (evt.IsEvent(typeof(ExampleOrkestraMessage)))
{
ExampleOrkestraMessage eom = new ExampleOrkestraMessage(evt.data.value);
// show message
Events.Add(() => {
userContext.text = eom.message;
});
}
}
//callback that receives the messages from the app channel
void AppEventSubscriber(object sender, ApplicationEvent evt)
{
//filtering the type of messages. This allows us to run different actions depending on the message type
if (evt.IsEvent(typeof(ExampleOrkestraMessage)))
{
ExampleOrkestraMessage eom = new ExampleOrkestraMessage(evt.value);
//if the message was not from the user itself -> Show message
if (eom.sender != agentId)
{
Events.Add(() => {
appContext.text = eom.message;
});
}
}
}
Create the message that the app will send through Orkestra
Different types of messages can be registered, with different structures and for different purposes. This is just an example.
/OrkestraLib/Example/Messages/ExampleOrkestraMessage.cs
namespace OrkestraLib
{
namespace Message
{
[Serializable]
public class ExampleOrkestraMessage : Message
{
public string message;
public ExampleOrkestraMessage(string json) : base(json) { }
public ExampleOrkestraMessage(string userId, string message) : base(typeof(ExampleOrkestraMessage).Name, userId)
{
this.message = message;
}
public override string FriendlyName()
{
return typeof(ExampleOrkestraMessage).Name;
}
}
}
}