In coherence, users cannot get the return value of the commands. However, it is sometimes important to get some sort of “response” or “callback” after a command is sent. For example, suppose some chat messages are stored in the simulator and I want to “download” them only once to the client. In this case, it will be convenient if I can send a “DownloadChatMessage” command to the simulator and get the data in a callback. Is there a way that coherence team recommends?
Two ways come to my mind:
- Create a unique ID and send it to the simulator as command parameter, then send the response from the simulator to the client in another command along with the ID:
public event Action<object, string> OnResponse;
public bool Request<T>(string methodName, Action<object> callback = null, params object[] args) {
var id = Guid.NewGuid().ToString(); // UUID
Action<object, string> onResponseAction = null;
onResponseAction = delegate(object response, string responseId) {
if (responseId == id) {
OnResponse -= onResponseAction;
if (callback != null) callback(response);
}
};
OnResponse += onResponseAction;
var t = typeof(T).ToString();
var requestArgs = new object[] {id, t, methodName};
requestArgs = requestArgs.Concat(args).ToArray();
if (!sync.HasStateAuthority) {
bool wasSent = sync.SendCommand(this.GetType(), "OnRequest", Coherence.MessageTarget.AuthorityOnly, requestArgs);
return wasSent;
} else {
OnRequest(requestArgs[0], requestArgs[1], requestArgs[2], requestArgs.Skip(3).ToArray());
return true;
}
}
public void OnRequest(object idObj, object tObj, object methodNameObj, params object[] args) {
var id = (string)idObj;
var t = (string)tObj;
var methodName = (string)methodNameObj;
var component = (MonoBehaviour)GetComponent(t);
var methodInfo = component.GetType().GetMethod(methodName);
// I think I need to add a filter here to make sure that the user can only call "allowed" methods?
var response = methodInfo.Invoke(component, args);
// Then somehow send the response in a new command to the requester.
}
There are 2 issues in this approach: I believe that there are some size limitations for the arguments. Also, how do I send the response to the requester only and not to all other clients?
- Upload the response along with an ID to a Redis database then download it on the requester device.
Any thoughts?