public static void Publish(RemoteMethodEvent remoteEvent, SPClient client) { if (remoteEvent.Type == RemoteMethodType.RETURN) { if (_callbacks.ContainsKey(remoteEvent.CallbackGuid)) { if (_callbacks.TryRemove(remoteEvent.CallbackGuid, out var cl)) { cl.SentRemoteMethodCall(remoteEvent); } } return; } ThreadPool.QueueUserWorkItem((callback) => { var subscribed = _subscribersInfo[remoteEvent.Channel].FirstOrDefault(s => !s.Client.Equals(client) && s.Client.ReadyForRMI && s.MethodName == remoteEvent.MethodName); if (subscribed != null) { subscribed.Client.SentRemoteMethodCall(remoteEvent); _callbacks.TryAdd(remoteEvent.CallbackGuid, client); } }); }
public async Task RemoteCall(string channel, string identifier, params object[] param) { var sw = Stopwatch.StartNew(); var callbackGuid = Guid.NewGuid().ToString(); _remoteMethodCallbacks.TryAdd(callbackGuid, new RemoteEventWait()); var remoteEvent = new RemoteMethodEvent() { Type = RemoteMethodType.CALL, MethodName = identifier, CallbackGuid = callbackGuid, Data = param, Channel = channel, }; var packetData = SerializeMessagePackToFrame(remoteEvent); await _sockSem.WaitAsync(); SendData(packetData, true); _remoteMethodCallbacks[callbackGuid].Event.WaitOne(); _remoteMethodCallbacks.TryRemove(callbackGuid, out _); sw.Stop(); _log.Debug($"Remote call object {identifier} time is {(sw.ElapsedMilliseconds / (float)1000)} seconds"); }
public async void RMIMethodCalled(RemoteMethodEvent remoteEvent) { if (remoteEvent.Type == RemoteMethodType.RETURN) { _remoteMethodCallbacks[remoteEvent.CallbackGuid].Result = remoteEvent; _remoteMethodCallbacks[remoteEvent.CallbackGuid].Event.Set(); return; } if (remoteEvent.Type != RemoteMethodType.CALL && remoteEvent.Type != RemoteMethodType.MOVE) { return; } if (_mountedHostedMethods.TryGetValue(remoteEvent.MethodName, out var targetMethod)) { var resultHeader = RemoteMethodType.RETURN; var parameters = new List <object>(); parameters.AddRange((object[])remoteEvent.Data); var localeMethodParameters = _selfHosted.GetType().GetMethod(remoteEvent.MethodName).GetParameters(); for (int i = 0; i < localeMethodParameters.Length; i++) { var isGenericType = parameters[i].GetType().IsGenericType; var localParameter = localeMethodParameters[i].ParameterType; if (localParameter.IsGenericType) { continue; } if (isGenericType) { parameters[i] = localParameter.ConvertProperties((Dictionary <object, object>)parameters[i]); } else if (localParameter.Equals(typeof(Guid))) { parameters[i] = Guid.Parse(parameters[i].ToString()); } else { parameters[i] = Convert.ChangeType(parameters[i], localParameter); } } var result = await targetMethod.Method.InvokeWrapper(targetMethod.HasAsyncResult, _selfHosted, parameters.ToArray()); var rmiEvent = new RemoteMethodEvent() { Type = resultHeader, CallbackGuid = remoteEvent.CallbackGuid, Data = result, Method = null, MethodName = remoteEvent.MethodName, Channel = _rmiChannel }; var packetData = SerializeMessagePackToFrame(rmiEvent); SendData(packetData); } }
public async Task <T> RemoteCall <T>(string channel, string identifier, params object[] param) { var sw = Stopwatch.StartNew(); var callbackGuid = Guid.NewGuid().ToString(); _remoteMethodCallbacks.TryAdd(callbackGuid, new RemoteEventWait()); var remoteEvent = new RemoteMethodEvent() { Type = RemoteMethodType.MOVE, MethodName = identifier, CallbackGuid = callbackGuid, Data = param, Channel = channel }; var packetData = SerializeMessagePackToFrame(remoteEvent); await _sockSem.WaitAsync(); SendData(packetData, true); _remoteMethodCallbacks[callbackGuid].Event.WaitOne(); var result = _remoteMethodCallbacks[callbackGuid].Result; _remoteMethodCallbacks.TryRemove(callbackGuid, out _); var typeofImplicit = typeof(T); sw.Stop(); if (result.Data.GetType().IsGenericType&& !typeofImplicit.IsGenericType) { var miResult = (T)Activator.CreateInstance(typeofImplicit).GetType().ConvertProperties((Dictionary <object, object>)result.Data); _log.Debug($"Remote call object {identifier} time is {sw.ElapsedMilliseconds / (float)1000} seconds"); return(miResult); } _log.Debug($"Remote call object {identifier} time is {sw.ElapsedMilliseconds / (float)1000} seconds"); return((T)Convert.ChangeType(result.Data, typeof(T))); }
public void SentRemoteMethodCall(RemoteMethodEvent remoteEvent) => SendData(SerializeMessagePackToFrame(remoteEvent));