//public async Task CallZomeFunctionAsync(string id, string instanceId, string zome, string function, ZomeFunctionCallBack callback, object paramsObject, bool autoConvertFieldsToHCStandard = false, bool matchIdToInstanceZomeFuncInCallback = true, bool cachReturnData = false)
        public async Task CallZomeFunctionAsync(string id, string instanceId, string zome, string function, ZomeFunctionCallBack callback, object paramsObject, bool matchIdToInstanceZomeFuncInCallback = true, bool cachReturnData = false)
        {
            Logger.Log("CallZomeFunctionAsync ENTER", LogType.Debug);
            _cacheZomeReturnDataLookup[id] = cachReturnData;

            if (cachReturnData)
            {
                if (_zomeReturnDataLookup.ContainsKey(id))
                {
                    Logger.Log("Caching Enabled so returning data from cach...", LogType.Warn);
                    Logger.Log(string.Concat("Id: ", _zomeReturnDataLookup[id].Id, ", Instance: ", _zomeReturnDataLookup[id].Instance, ", Zome: ", _zomeReturnDataLookup[id].Zome, ", Zome Function: ", _zomeReturnDataLookup[id].ZomeFunction, ", Is Zome Call Successful: ", _zomeReturnDataLookup[id].IsCallSuccessful ? "True" : "False", ", Raw Zome Return Data: ", _zomeReturnDataLookup[id].RawZomeReturnData, ", Zome Return Data: ", _zomeReturnDataLookup[id].ZomeReturnData, ", JSON Raw Data: ", _zomeReturnDataLookup[id].RawJSONData), LogType.Info);

                    if (callback != null)
                    {
                        callback.DynamicInvoke(this, _zomeReturnDataLookup[id]);
                    }

                    OnZomeFunctionCallBack?.Invoke(this, _zomeReturnDataLookup[id]);
                    Logger.Log("CallZomeFunctionAsync EXIT", LogType.Debug);
                    return;
                }
            }

            if (matchIdToInstanceZomeFuncInCallback)
            {
                _instanceLookup[id] = instanceId;
                _zomeLookup[id]     = zome;
                _funcLookup[id]     = function;
            }

            if (callback != null)
            {
                _callbackLookup[id] = callback;
            }


            //if (autoConvertFieldsToHCStandard)
            //{
            //    string json = JsonConvert.SerializeObject(paramsObject);
            //    JObject data = JObject.Parse(json);
            //    //data.Next.Replace(new JToken()

            //    data.SelectToken("instance_stats.test-instance.number_delayed_validations").ToString()),
            //}

            await SendMessageAsync(JsonConvert.SerializeObject(
                                       new
            {
                jsonrpc = "2.0",
                id,
                method  = "call",
                @params = new { instance_id = instanceId, zome, function, args = paramsObject }
                //@params = new { instance_id = instanceId, zome, function, @params = paramsObject }
            }
                                       ));

            Logger.Log("CallZomeFunctionAsync EXIT", LogType.Debug);
        }
Beispiel #2
0
        public async Task CallZomeFunctionAsync(string id, string instanceId, string zome, string function, ZomeFunctionCallBack callback, object paramsObject, bool matchIdToInstanceZomeFuncInCallback = true, bool cachReturnData = false)
        {
            Logger.Log("CallZomeFunctionAsync ENTER", LogType.Debug);
            _cacheZomeReturnDataLookup[id] = cachReturnData;

            if (cachReturnData)
            {
                if (_zomeReturnDataLookup.ContainsKey(id))
                {
                    Logger.Log("Caching Enabled so returning data from cach...", LogType.Warn);
                    Logger.Log(string.Concat("Id: ", _zomeReturnDataLookup[id].Id, ", Instance: ", _zomeReturnDataLookup[id].Instance, ", Zome: ", _zomeReturnDataLookup[id].Zome, ", Zome Function: ", _zomeReturnDataLookup[id].ZomeFunction, ", Is Zome Call Successful: ", _zomeReturnDataLookup[id].IsCallSuccessful ? "True" : "False", ", Raw Zome Return Data: ", _zomeReturnDataLookup[id].RawZomeReturnData, ", Zome Return Data: ", _zomeReturnDataLookup[id].ZomeReturnData, ", JSON Raw Data: ", _zomeReturnDataLookup[id].RawJSONData), LogType.Info);

                    if (callback != null)
                    {
                        callback.DynamicInvoke(this, _zomeReturnDataLookup[id]);
                    }

                    OnZomeFunctionCallBack?.Invoke(this, _zomeReturnDataLookup[id]);
                    Logger.Log("CallZomeFunctionAsync EXIT", LogType.Debug);
                    return;
                }
            }

            if (matchIdToInstanceZomeFuncInCallback)
            {
                _instanceLookup[id] = instanceId;
                _zomeLookup[id]     = zome;
                _funcLookup[id]     = function;
            }

            if (callback != null)
            {
                _callbackLookup[id] = callback;
            }

            await SendMessageAsync(JsonConvert.SerializeObject(
                                       new
            {
                jsonrpc = "2.0",
                id,
                method  = "call",
                @params = new { instance_id = instanceId, zome, function, @params = paramsObject }
            }
                                       ));

            Logger.Log("CallZomeFunctionAsync EXIT", LogType.Debug);
        }
        private async Task StartListen()
        {
            var buffer = new byte[Config.ReceiveChunkSize == 0 ? ReceiveChunkSizeDefault : Config.ReceiveChunkSize];

            Logger.Log(string.Concat("Listening on ", EndPoint, "..."), LogType.Info);

            try
            {
                while (WebSocket.State == WebSocketState.Open)
                {
                    var stringResult = new StringBuilder();

                    WebSocketReceiveResult result;
                    do
                    {
                        if (Config.NeverTimeOut)
                        {
                            result = await WebSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                        }
                        else
                        {
                            using (var cts = new CancellationTokenSource((Config.TimeOutSeconds == 0 ? TimeOutSecondsDefault : Config.TimeOutSeconds) * 1000))
                                result = await WebSocket.ReceiveAsync(new ArraySegment <byte>(buffer), cts.Token);
                        }

                        if (result.MessageType == WebSocketMessageType.Close)
                        {
                            string msg = "Closing because received close message from Holochain."; //TODO: Move all strings to constants at top or resources.strings
                            await WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, msg, CancellationToken.None);

                            OnDisconnected?.Invoke(this, new DisconnectedEventArgs {
                                EndPoint = EndPoint, Reason = msg
                            });
                            Logger.Log(msg, LogType.Info);

                            ShutDownConductors();

                            //AttemptReconnect(); //TODO: Not sure re-connect here?
                        }
                        else
                        {
                            var str = Encoding.UTF8.GetString(buffer, 0, result.Count);
                            stringResult.Append(str);
                        }
                    } while (!result.EndOfMessage);

                    string  rawData = stringResult.ToString();
                    JObject data    = JObject.Parse(rawData);

                    bool   isConductorDebugInfo = false;
                    string id = "";

                    if (data.ContainsKey("type"))
                    {
                        isConductorDebugInfo = true;
                    }

                    Logger.Log(string.Concat("Received Data: ", rawData), LogType.Info);
                    OnDataReceived?.Invoke(this, new DataReceivedEventArgs {
                        EndPoint = EndPoint, RawJSONData = rawData, WebSocketResult = result, IsConductorDebugInfo = isConductorDebugInfo
                    });

                    if (data.ContainsKey("id"))
                    {
                        id = data["id"].ToString();
                    }

                    if (isConductorDebugInfo)
                    {
                        // Conducor Debug Info.
                        ConductorDebugCallBackEventArgs args = new ConductorDebugCallBackEventArgs {
                            EndPoint = EndPoint, RawJSONData = rawData, NumberDelayedValidations = Convert.ToInt32(data.SelectToken("instance_stats.test-instance.number_delayed_validations").ToString()), NumberHeldAspects = Convert.ToInt32(data.SelectToken("instance_stats.test-instance.number_held_aspects").ToString()), NumberHeldEntries = Convert.ToInt32(data.SelectToken("instance_stats.test-instance.number_held_entries").ToString()), NumberPendingValidations = Convert.ToInt32(data.SelectToken("instance_stats.test-instance.number_pending_validations").ToString()), NumberRunningZomeCalls = Convert.ToInt32(data.SelectToken("instance_stats.test-instance.number_running_zome_calls").ToString()), Offline = Convert.ToBoolean(data.SelectToken("instance_stats.test-instance.offline").ToString()), Type = data.SelectToken("type").ToString(), WebSocketResult = result
                        };
                        Logger.Log(string.Concat("Conductor Debug Info Detected. Raw JSON Data: ", rawData, "NumberDelayedValidations: ", args.NumberDelayedValidations, "NumberDelayedValidations: ", args.NumberHeldAspects, "NumberHeldEntries: ", args.NumberHeldEntries, "NumberPendingValidations: ", args.NumberPendingValidations, "NumberRunningZomeCalls; ", args.NumberRunningZomeCalls, "Offline: ", args.Offline, "Type: ", args.Type), LogType.Info);
                        OnConductorDebugCallBack?.Invoke(this, args);
                    }
                    else if (data.ContainsKey("signal"))
                    {
                        //Signals.
                        SignalsCallBackEventArgs args = new SignalsCallBackEventArgs(id, EndPoint, true, rawData, (SignalsCallBackEventArgs.SignalTypes)Enum.Parse(typeof(SignalsCallBackEventArgs.SignalTypes), data.SelectToken("signal_type").ToString(), true), data.SelectToken("name").ToString(), data.SelectToken("arguments"), result);
                        Logger.Log(string.Concat("Signals data detected. Id: ", id, ", Raw JSON Data: ", rawData, "Name: ", args.Name, "SignalType: ", args.SignalType, "Arguments: ", args.Arguments), LogType.Info);
                        OnSignalsCallBack?.Invoke(this, args);
                    }
                    else if (data.SelectToken("result[0].agent") != null)
                    {
                        // Get Instance Info.
                        GetInstancesCallBackEventArgs args = new GetInstancesCallBackEventArgs(id, EndPoint, true, data["result"].ToString(), new List <string>()
                        {
                            data.SelectToken("result[0].id").ToString()
                        }, data.SelectToken("result[0].dna").ToString(), data.SelectToken("result[0].agent").ToString(), result);
                        Logger.Log(string.Concat("Get Instances data detected. Id: ", id, ", EndPoint: ", EndPoint, ", agent: ", args.Agent, ", DNA: ", args.DNA, ", Instances: ", string.Join(",", args.Instances), ", Raw JSON Data: ", rawData), LogType.Info);

                        if (_cachInstancesReturnData)
                        {
                            _instancesCache = args;
                        }

                        // _taskCompletionSourceGetInstance.SetResult(args);
                        OnGetInstancesCallBack?.Invoke(this, args);
                    }
                    else
                    {
                        //Zome Return Call.
                        string rawZomeReturnData = "";

                        if (data.ContainsKey("result"))
                        {
                            rawZomeReturnData = data["result"].ToString();
                        }

                        string zomeReturnData       = string.Empty;
                        bool   isZomeCallSuccessful = false;

                        if (rawZomeReturnData.Length >= 4 && rawZomeReturnData.Substring(2, 2).ToUpper() == "OK")
                        {
                            isZomeCallSuccessful = true;
                            zomeReturnData       = rawZomeReturnData.Substring(7, rawZomeReturnData.Length - 9);
                            //zomeReturnData = rawZomeReturnData.Substring(6, rawZomeReturnData.Length - 8);
                        }
                        //else if (rawZomeReturnData.Substring(0,3).ToUpper() == "ERR")
                        else if (rawZomeReturnData.Length > 1)
                        {
                            zomeReturnData = rawZomeReturnData.Substring(1, rawZomeReturnData.Length - 2);
                        }
                        //zomeReturnData = rawZomeReturnData.Substring(8, rawZomeReturnData.Length - 11);

                        ZomeFunctionCallBackEventArgs args = new ZomeFunctionCallBackEventArgs(id, this.EndPoint, GetItemFromCache(id, _instanceLookup), GetItemFromCache(id, _zomeLookup), GetItemFromCache(id, _funcLookup), isZomeCallSuccessful, rawZomeReturnData, zomeReturnData, rawData, result);
                        Logger.Log(string.Concat("Zome result data detected. Id: ", args.Id, ", Instance: ", args.Instance, ", Zome: ", args.Zome, ", Zome Function: ", args.ZomeFunction, ", Is Zome Call Successful: ", args.IsCallSuccessful ? "True" : "False", ", Raw Zome Return Data: ", args.RawZomeReturnData, ", Zome Return Data: ", args.ZomeReturnData, ", JSON Raw Data: ", args.RawJSONData), LogType.Info);

                        if (_callbackLookup.ContainsKey(id) && _callbackLookup[id] != null)
                        {
                            _callbackLookup[id].DynamicInvoke(this, args);
                        }

                        OnZomeFunctionCallBack?.Invoke(this, args);

                        // If the zome call requested for this to be cached then stick it in cach.
                        if (_cacheZomeReturnDataLookup[id])
                        {
                            _zomeReturnDataLookup[id] = args;
                        }

                        _instanceLookup.Remove(id);
                        _zomeLookup.Remove(id);
                        _funcLookup.Remove(id);
                        _callbackLookup.Remove(id);
                    }
                }
            }

            catch (TaskCanceledException ex)
            {
                string msg = string.Concat("Connection timed out after ", (Config.TimeOutSeconds == 0 ? TimeOutSecondsDefault : Config.TimeOutSeconds), " seconds.");
                OnDisconnected?.Invoke(this, new DisconnectedEventArgs {
                    EndPoint = EndPoint, Reason = msg
                });
                HandleError(msg, ex);
                await AttemptReconnect();
            }

            catch (Exception ex)
            {
                OnDisconnected?.Invoke(this, new DisconnectedEventArgs {
                    EndPoint = EndPoint, Reason = string.Concat("Error occured: ", ex)
                });
                HandleError("Disconnected because an error occured.", ex);
                await AttemptReconnect();
            }

            finally
            {
                WebSocket.Dispose();
            }
        }