static BinaryResourceAccessor()
        {
            FetchHandlers = new DictionaryTS<eBinaryResourceLocationType, Func<BinaryResourceDescriptor, byte[]>>();

            FetchHandlers.Add(eBinaryResourceLocationType.Http, HttpFetchHandler);
            FetchHandlers.Add(eBinaryResourceLocationType.RedisDB, RedisDBFetchHandler);
        }
        static BinaryResourceAccessor()
        {
            FetchHandlers = new DictionaryTS <eBinaryResourceLocationType, Func <BinaryResourceDescriptor, byte[]> >();

            FetchHandlers.Add(eBinaryResourceLocationType.Http, HttpFetchHandler);
            FetchHandlers.Add(eBinaryResourceLocationType.RedisDB, RedisDBFetchHandler);
        }
Beispiel #3
0
 //------------------------------------------------------------------------------------------------------------------------
 private void RemoteNode_OnChannelOpen(RemoteNode RemoteNode)
 {
     BrotherNodes.Add(RemoteNode.RemoteNodeKey, RemoteNode);
     //raise event
     if (OnRemoteNodeAssociation != null)
     {
         Task.Run(() => { try { OnRemoteNodeAssociation?.Invoke(RemoteNode); } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception"); } });
     }
 }
Beispiel #4
0
        //------------------------------------------------------------------------------------------------------------------------
        void HandleNewPacket(byte[] data, string addr)
        {
            try
            {
                //deserialize packet
                IDiscoveryMessageBase msg;
                try
                {
                    msg = Tools.Marshalling.ToObject(DiscoveryMessageType, data) as IDiscoveryMessageBase;
                }
                catch { return; }

                //is it me? (then discard msg)
                if (msg.Id == 0 || msg.Id == myID)
                {
                    return;
                }

                //create remote id
                var remID = new RemoteEndpointID()
                {
                    IPAddress = addr, ID = msg.Id
                };

                //examine existing association
                var info = DiscoveredEndpoints.TryGetOrDefault(remID);
                if (info == null)
                {
                    DebugEx.TraceLog($"LANDiscoverer : Discovered new endpoint. (ip:{addr} id:{msg.Id} flags:{msg.Flags})");
                    //create info
                    info = new RemoteEndpointInfo
                    {
                        ID = remID,
                        LastMessageTimestamp = DateTime.Now,
                        LastDiscoveryMessage = msg,
                    };
                    //add to discovered nodes
                    DiscoveredEndpoints.Add(remID, info);
                    //raise event
                    OnNewEndpointDiscovered?.Invoke(info);
                }

                //custom handle?
                OnEndpointMsgRx?.Invoke(info, msg);

                //update discovery message and timestamp
                Interlocked.Exchange(ref info.LastDiscoveryMessage, msg);
                info.LastMessageTimestamp = DateTime.Now;
            }
            catch (Exception ex) { DebugEx.TraceError(ex, "DiscoveryTaskEntryPoint error"); }
        }
Beispiel #5
0
        //------------------------------------------------------------------------------------------------------------------------
        public object GetSingleValue <Req>(Req data)
        {
            var syncid = GetNewSyncId();
            var w      = new Waiter();

            lock (PendingRequests)
                PendingRequests.Add(syncid, w);
            //construct sharppy msg
            SharpPy msg = new SharpPy()
            {
                isRequest = true,
                watcherid = WatcherId,
                syncid    = syncid,
                pin       = this.sensor.Pin.ToString(),
                operation = (data as SharpPy).operation,
                payload   = (data as SharpPy).payload,
            };

            lock (w)
            {
                this.sharppyiface.Send2python(msg);
                Monitor.Wait(w);
            }
            lock (PendingRequests)
                PendingRequests.Remove(syncid);

            if (w.response != null)
            {
                if (w.response != prevData && w.response != "255" && w.response != "65535")
                {
                    prevData = w.response;
                    DebugEx.TraceLog("CONT: wId:" + WatcherId + " sId:" + syncid + " response:" + w.response);
                    return(this.sensor.DeserializePayload(w.response));
                }
                //else
                //    DebugEx.TraceLog("DROP: wId:" + WatcherId + " sId:" + syncid + " response:" + w.response);
            }
            return(null);
        }
Beispiel #6
0
        private void GotButton(Bdaddr bdAddr)
        {
            DebugEx.TraceLog("Got Button");
            var thing = flicThings.TryGetOrDefault(bdAddr);

            if (thing == null)
            {
                thing = ThingTools.FlicThing.CreateThing(bdAddr.ToString().Replace(":", ""), bdAddr.ToString());
                thing = AddThing(thing);
                flicThings.Add(bdAddr, thing);
            }

            DebugEx.TraceLog("===========>Add Button Thing Completed");
            var channel = ButtonChannels.TryGetOrDefault(bdAddr);

            if (channel == null)
            {
                DebugEx.TraceLog("===========>New Channel is created");
                channel = new ButtonConnectionChannel(bdAddr);

                channel.CreateConnectionChannelResponse += (sender1, eventArgs) =>
                {
                    if (eventArgs.Error == CreateConnectionChannelError.NoError)
                    {
                        _channelConnected((ButtonConnectionChannel)sender1);
                    }
                    else
                    {
                        DebugEx.TraceError(((ButtonConnectionChannel)sender1).BdAddr.ToString() + " could not be connected");
                    }
                };
                channel.Removed += (sender1, eventArgs) =>
                {
                    _channelDisconnected((ButtonConnectionChannel)sender1);
                };
                channel.ConnectionStatusChanged += (sender1, eventArgs) =>
                {
                    var chan = (ButtonConnectionChannel)sender1;
                    if (eventArgs.ConnectionStatus == ConnectionStatus.Disconnected)
                    {
                        _channelDisconnected(chan);
                    }
                };
                channel.ButtonSingleOrDoubleClickOrHold += (sender1, eventArgs) =>
                {
                    var chan      = (ButtonConnectionChannel)sender1;
                    var thisThing = flicThings.TryGetOrDefault(chan.BdAddr);
                    if (thisThing == null)
                    {
                        return;
                    }

                    DebugEx.TraceLog(eventArgs.ClickType + " for " + thisThing.Name + " (key:" + thisThing.ThingKey + ")");
                    switch (eventArgs.ClickType)
                    {
                    case ClickType.ButtonSingleClick:
                        SetPortState(PortKey.BuildFromArbitraryString(thisThing.ThingKey, ThingTools.FlicThing.SingleClick), "True");
                        break;

                    case ClickType.ButtonDoubleClick:
                        SetPortState(PortKey.BuildFromArbitraryString(thisThing.ThingKey, ThingTools.FlicThing.DoubleClick), "True");
                        break;

                    case ClickType.ButtonHold:
                        SetPortState(PortKey.BuildFromArbitraryString(thisThing.ThingKey, ThingTools.FlicThing.LongClick), "True");
                        break;

                    default:
                        break;
                    }

                    if (!ButtonChannels.ContainsKey(chan.BdAddr))
                    {
                        _channelConnected(chan);
                    }
                };

                //try to add channel
                _flicClient.AddConnectionChannel(channel);
                DebugEx.TraceLog("===========>Add Connection Channel Completed");

                foreach (var navctx in NavigationContext.Values)
                {
                    DebugEx.TraceLog("===========>navctx.CurrentPage.Title: " + navctx.CurrentPage.Title);
                    if (navctx.CurrentPage.Title == "Flic Pairing")
                    {
                        DebugEx.TraceLog("=====>here I am <======");
                        navctx.GoBack();
                        navctx.UpdateCurrentPage(createDiscoverPage());
                    }
                }
            }
        }
Beispiel #7
0
        //------------------------------------------------------------------------------------------------------------------------
        public GenericRsp HandleGraphDeploymentReq(GraphDeploymentReq req, bool SupressSave)
        {
            lock (locker)
            {
                var res = new GenericRsp();
                try
                {
                    //get graphkey
                    var graphkey = (GraphKey)req.GraphKey;
                    if (graphkey.IsInvalid)
                    {
                        res.IsSuccess = false;
                        res.Message   = "Invalid GraphKey";
                        return(res);
                    }
                    if (graphkey.NodeId != this.Node.NodeKey.NodeID)
                    {
                        res.IsSuccess = false;
                        res.Message   = "Invalid NodeID in GraphKey";
                        return(res);
                    }

                    //collect sets
                    var sets = Node.BeginActiveThingsUpdate();

                    //deploy or undeploy?
                    if (req.IsDeployed)
                    {
                        //deserialize graph descriptor
                        GraphDescriptor graphDescriptor;
                        try { graphDescriptor = GraphBuilder.GetGraphDescriptorFromJson(req.GraphDescriptor, false); }
                        catch (Exception ex)
                        {
                            DebugEx.Assert(ex, "Could not deserialize graph descriptor");
                            res.IsSuccess = false;
                            res.Message   = "Could not deserialize graph descriptor";
                            return(res);
                        }
                        graphDescriptor.GraphKey = graphkey;

                        //Build Graph
                        Graph graph;
                        try { graph = BuildGraph(graphDescriptor); }
                        catch (Exception ex)
                        {
                            DebugEx.Assert(ex, "Could not build graph from graph descriptor (unhandled exception)");
                            res.IsSuccess = false;
                            res.Message   = "Could not  build graph from graph descriptor (unhandled exception)";
                            return(res);
                        }
                        if (graph == null)
                        {
                            DebugEx.Assert("Could not build graph from graph descriptor");
                            res.IsSuccess = false;
                            res.Message   = "Could not  build graph from graph descriptor";
                            return(res);
                        }

                        //set key
                        graph.GraphKey = graphkey;

                        //do i already have it?
                        if (Graphs.ContainsKey(graphkey))
                        {
                            //invalidate graph
                            _GraphManager.InvalidateGraph(graphkey);
                            //remove information
                            Graphs.Remove(graphkey);
                        }

                        //try deploy graph
                        try
                        {
                            Exception exception;
                            var       depres = graph.OnDeploy(true, null, out exception);
                            if (!depres)
                            {
                                res.IsSuccess = false;
                                res.Message   = "Graph OnDeploy() failed. Message : " + (exception?.Message ?? "null");
                                return(res);
                            }
                        }
                        catch (Exception ex)
                        {
                            DebugEx.Assert(ex, "Graph OnDeploy() failed");
                            res.IsSuccess = false;
                            res.Message   = "Graph OnDeploy() failed. Message : " + ex.Message;
                            return(res);
                        }

                        //add to lookup
                        var gi = new GraphInfo()
                        {
                            GraphKey              = graphkey,
                            GraphDescriptor       = graphDescriptor,
                            GraphDescriptorString = req.GraphDescriptor,
                            Graph = graph,
                        };
                        Graphs.Add(graphkey, gi);

                        //save!
                        if (IsInitialized && !SupressSave)
                        {
                            Save();
                        }

                        //associate block keys
                        foreach (var thingblock in graph.Blocks.OfType <BaseThings>())
                        {
                            //Add to Thing2Block set
                            {
                                //find block key set
                                var set = ThingKey2BlockKey.TryGetOrDefault(thingblock.ThingKey);
                                if (set == null)
                                {
                                    set = new HashSetTS <BlockKey>();
                                    ThingKey2BlockKey.Add(thingblock.ThingKey, set);
                                }
                                //add to loockup set
                                set.Add(thingblock.BlockKey);
                            }

                            //Add only for thingIn
                            if (thingblock.IsThingIn)
                            {
                                //find block key set
                                var set = ThingKey2ThingInBlockKey.TryGetOrDefault(thingblock.ThingKey);
                                if (set == null)
                                {
                                    set = new HashSetTS <BlockKey>();
                                    ThingKey2ThingInBlockKey.Add(thingblock.ThingKey, set);
                                }
                                //add to loockup set
                                set.Add(thingblock.BlockKey);
                            }
                        }

                        //Handle Deploy
                        res.IsSuccess = true;
                        res.Message   = "Graph Deployed Successfully";
                    }
                    else
                    {
                        //Handle UnDeploy
                        if (Graphs.ContainsKey(graphkey) == false)
                        {
                            res.IsSuccess = true;
                            res.Message   = "Graph Undeployed Successfully (was not deployed)";
                        }
                        else
                        {
                            //get graph
                            var gi    = Graphs[graphkey];
                            var graph = gi.Graph;
                            //inform graph
                            Exception exception;
                            try
                            {
                                if (graph.OnUndeploy(null, out exception) == false)
                                {
                                    DebugEx.Assert(exception, "Graph OnUndeploy failed");
                                }
                            }
                            catch (Exception ex) { DebugEx.Assert(ex, "Graph OnUndeploy failed"); }
                            //invalidate graph
                            _GraphManager.InvalidateGraph(graphkey);
                            //remove information
                            Graphs.Remove(graphkey);
                            //save!
                            if (IsInitialized && !SupressSave)
                            {
                                Save();
                            }
                            //disassociate block keys
                            if (graph != null)
                            {
                                foreach (var thingblock in gi.Graph.Blocks.OfType <BaseThings>())
                                {
                                    //remove from thing2block
                                    {
                                        var set = ThingKey2BlockKey.TryGetOrDefault(thingblock.ThingKey);
                                        if (set != null)
                                        {
                                            set.Remove(thingblock.BlockKey);
                                        }
                                    }

                                    //remove from thignIn2block
                                    if (thingblock.IsThingIn)
                                    {
                                        var set = ThingKey2ThingInBlockKey.TryGetOrDefault(thingblock.ThingKey);
                                        if (set != null)
                                        {
                                            set.Remove(thingblock.BlockKey);
                                        }
                                    }
                                }
                            }
                            //done
                            res.IsSuccess = true;
                            res.Message   = "Graph Undeployed Successfully";
                        }
                    }

                    //finish update
                    Node.EndActiveThingsUpdate(sets);
                }
                catch (Exception ex)
                {
                    res.IsSuccess = false;
                    res.Message   = "Unhandled exception in GraphDeploymentReq(). Message=" + ex.Message;
                }
                finally
                {
                    //begin activation state snapshot
                    var sets = Node.BeginActiveThingsUpdate();

                    //update active ports/things
                    var activeThings = ThingKey2BlockKey.Where(kv => kv.Value.Count > 0)
                                       .Select(kv => Node.Things.TryGetOrDefaultReadOnly(kv.Key))
                                       .WhereNotNull().ToHashSetTS();
                    var activeThingKeys = activeThings.Select(t => (ThingKey)t.ThingKey).ToHashSetTS();

                    var activePorts     = activeThings.SelectMany(t => t.Ports).ToHashSetTS();
                    var activePortsKeys = activePorts.Select(p => (PortKey)p.PortKey).ToHashSetTS();

                    //update sets
                    Interlocked.Exchange(ref _ActiveThings, activeThings);
                    Interlocked.Exchange(ref _ActivePorts, activePorts);
                    Interlocked.Exchange(ref _ActiveThingKeys, activeThingKeys);
                    Interlocked.Exchange(ref _ActivePortKeys, activePortsKeys);

                    //trigger node thing activation update
                    Node.EndActiveThingsUpdate(sets);
                }
                //return result msg
                return(res);
            }
        }
Beispiel #8
0
        //------------------------------------------------------------------------------------------------------------------------
        private IEnumerable <Thing> SetupSerialPortThing()
        {
            // Clean old things
            things.Clear();

            // mNode transport conncted event
            {
                var isTransportConnected = new Port()
                {
                    ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output,
                    Name        = "Connected",
                    State       = "",
                    ConfFlags   = ePortConf.IsTrigger,
                    Type        = Yodiwo.API.Plegma.ePortType.Boolean,
                    PortKey     = PortKey.BuildFromArbitraryString("$ThingKey$", "0")
                };
                Ports.Add("isTransportConnected", isTransportConnected);

                var connectionTimestamp = new Port()
                {
                    ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output,
                    Name        = "Timestamp",
                    State       = "",
                    ConfFlags   = ePortConf.None,
                    Type        = Yodiwo.API.Plegma.ePortType.Timestamp,
                    PortKey     = PortKey.BuildFromArbitraryString("$ThingKey$", "1")
                };
                Ports.Add("connectionTimestamp", connectionTimestamp);

                var t = new Yodiwo.API.Plegma.Thing()
                {
                    ThingKey = ThingKey.BuildFromArbitraryString("$NodeKey$", CreateThingKey("0")),
                    Type     = "",
                    Name     = "Transport",
                    Config   = new List <ConfigParameter>(),
                    UIHints  = new ThingUIHints()
                    {
                        IconURI = "http://simpleicon.com/wp-content/uploads/cloud-connection-1.png",
                    },

                    Ports = new List <Port>()
                    {
                        isTransportConnected,
                        connectionTimestamp
                    }
                };

                t = AddThing(t);
                things.Add("Transport", t);
            }

            // mNode periodic send
            {
                var periodicTimestamp = new Port()
                {
                    ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output,
                    Name        = "Timestamp",
                    State       = "",
                    ConfFlags   = ePortConf.None,
                    Type        = Yodiwo.API.Plegma.ePortType.Timestamp,
                    PortKey     = PortKey.BuildFromArbitraryString("$ThingKey$", "0")
                };
                Ports.Add("periodicTimestamp", periodicTimestamp);

                var t = new Yodiwo.API.Plegma.Thing()
                {
                    ThingKey = ThingKey.BuildFromArbitraryString("$NodeKey$", CreateThingKey("1")),
                    Type     = "",
                    Name     = "Periodic",
                    Config   = new List <ConfigParameter>()
                    {
                        // TODO: Use the actual value of the thing
                        new ConfigParameter()
                        {
                            Description = "Period Seconds",
                            Name        = "Period",
                            Value       = "10"
                        }
                    },
                    UIHints = new ThingUIHints()
                    {
                        IconURI = "https://openreferral.org/wp-content/uploads/2015/02/icon_4034-300x300.png",
                    },

                    Ports = new List <Port>()
                    {
                        periodicTimestamp
                    }
                };

                t = AddThing(t);
                things.Add("Periodic", t);
            }

            // mNode Ping
            {
                var echoPortOut = new Port()
                {
                    ioDirection = Yodiwo.API.Plegma.ioPortDirection.Output,
                    Name        = "Echo",
                    State       = "",
                    ConfFlags   = ePortConf.None,
                    Type        = Yodiwo.API.Plegma.ePortType.String,
                    PortKey     = PortKey.BuildFromArbitraryString("$ThingKey$", "0")
                };
                Ports.Add("echoPortOut", echoPortOut);

                var echoPortIn = new Port()
                {
                    ioDirection = Yodiwo.API.Plegma.ioPortDirection.Input,
                    Name        = "Echo",
                    State       = "",
                    ConfFlags   = ePortConf.None,
                    Type        = Yodiwo.API.Plegma.ePortType.String,
                    PortKey     = PortKey.BuildFromArbitraryString("$ThingKey$", "1")
                };
                Ports.Add("echoPortIn", echoPortIn);

                var t = new Yodiwo.API.Plegma.Thing()
                {
                    ThingKey = ThingKey.BuildFromArbitraryString("$NodeKey$", CreateThingKey("2")),
                    Type     = "",
                    Name     = "Ping",
                    Config   = new List <ConfigParameter>(),
                    UIHints  = new ThingUIHints()
                    {
                        IconURI = "https://apk-dl.com/detail/image/com.lipinic.ping-w250.png",
                    },

                    Ports = new List <Port>()
                    {
                        echoPortIn,
                        echoPortOut
                    }
                };

                t = AddThing(t);
                things.Add("Ping", t);
            }

            return(things.Values);
        }
Beispiel #9
0
        //------------------------------------------------------------------------------------------------------------------------
        void HandleNewConnection(Socket newsocket)
        {
            try
            {
                #region check reconnection throttle
                try
                {
                    //setup socket
                    newsocket.ReceiveTimeout = -1;
                    newsocket.SendTimeout    = 60 * 1000;

#if NETFX
                    var re = newsocket.RemoteEndPoint.GetIPAddress().ToStringInvariant();
#elif UNIVERSAL
                    var re = newsocket.Information.RemoteAddress.ToStringInvariant();
#endif
                    //filtering
                    if (OnNewSocketConnectionFilter != null && OnNewSocketConnectionFilter(this, re) == false)
                    {
#if NETFX
                        try { newsocket.Close(); } catch { }
#endif
                        try { newsocket.Dispose(); } catch { }
                        DebugEx.TraceWarning("Connection from " + re + " closed from filter");
                        return;
                    }

                    if (IsReconnectionThrottleEnabled && re != "127.0.0.1" && re != "localhost") //no reconnection throttle for localhost connections
                    {
                        var rbe = reconnectThrottleBookKeeper.TryGetOrDefault(re);
                        if (rbe == null)
                        {
                            rbe = new ReconnectionBookkeepEntry()
                            {
                                ConnectionTimestamp = DateTime.Now + TimeSpan.FromMilliseconds(100),
                                Connections         = 1,
                            };
                            reconnectThrottleBookKeeper.ForceAdd(re, rbe);
                        }
                        else
                        {
                            if (++rbe.Connections > ReconnectionThrottleAfterConnectionCount)
                            {
                                var elapsed = DateTime.Now - rbe.ConnectionTimestamp;
                                if (elapsed < ReconnectionThrottleTimeout)
                                {
#if NETFX
                                    try { newsocket.Close(); } catch { }
#endif
                                    try { newsocket.Dispose(); } catch { }
                                    DebugEx.TraceWarning("Connection from " + re + " closed due to reconnection throttle (" + elapsed.Seconds + " sec)");
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex) { DebugEx.TraceWarning(ex, "YPServer Reconnection throttle exception"); }

                //cleanup old entries
                reconnectThrottleBookKeeper.RemoveWhere(e => DateTime.Now - e.Value.ConnectionTimestamp > ReconnectionThrottleTimeout);
                #endregion

                //start task new connection
                Task.Run(() =>
                {
                    ServerChannel channel = null;
                    string channelKey     = null;

                    Thread.Sleep(MathTools.GetRandomNumber(1, 100));
                    try
                    {
                        //check
#if NETFX
                        if (!newsocket.Connected)
                        {
                            DebugEx.TraceWarning("YPServer newsocket not connected?");
                            try { newsocket.Close(); } catch { }
                            return;
                        }
#endif
                        //create channel
                        var con = ChannelConstructor;
                        channel = con == null ? new ServerChannel(this, Protocols, SupportedChannelSerializationModes, PreferredChannelSerializationModes, newsocket) : con(Protocols, newsocket);
                        if (channel == null)
                        {
                            DebugEx.Assert("Could not create channel");
#if NETFX
                            try { newsocket.Close(); } catch { }
#endif
                            try { newsocket.Dispose(); } catch { }
                            return;
                        }

                        //add to set
                        lock (_Channels)
                        {
                            //generate unique key
                            while (IssuedKeys.ContainsKey(channelKey = MathTools.GenerateRandomAlphaNumericString(64)))
                            {
                                ;
                            }
                            //set on channel
                            channel._ChannelKey = channelKey;
                            //add to lookups
                            _Channels.Add(channel);
                            IssuedKeys.Add(channelKey, channel);
                        }

                        //start task timeout monitor
                        bool setupFinished = false;
                        Task.Run(() =>
                        {
                            try
                            {
                                //wait
                                Thread.Sleep(30000);
                                //check
                                if (!setupFinished)
                                {
                                    DebugEx.TraceLog($"ServerChannel setup timeout ({channel})");
                                    try { channel.Close("ServerChannel setup timeout"); } catch { }
#if NETFX
                                    try { newsocket?.Close(); } catch { }
#endif
                                    try { newsocket?.Dispose(); } catch { }

                                    //remove from lookups
                                    lock (_Channels)
                                    {
                                        if (channel != null)
                                        {
                                            _Channels.Remove(channel);
                                        }
                                        if (channelKey != null)
                                        {
                                            IssuedKeys.Remove(channelKey);
                                        }
                                    }
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                DebugEx.Assert(ex, $"Unhandled exception ({channel})");
#if NETFX
                                try { newsocket?.Close(); } catch { }
#endif
                                try { newsocket?.Dispose(); } catch { }

                                //remove from lookups
                                lock (_Channels)
                                {
                                    if (channel != null)
                                    {
                                        _Channels.Remove(channel);
                                    }
                                    if (channelKey != null)
                                    {
                                        IssuedKeys.Remove(channelKey);
                                    }
                                }
                                return;
                            }
                        });

                        //set serializer
                        channel.MsgPack = MsgPackSerializer;

                        //setup channel socket
                        if (channel.SetupServerSocket() == false)
                        {
#if NETFX
                            try { newsocket?.Close(); } catch { }
#endif
                            try { newsocket?.Dispose(); } catch { }

                            //remove from lookups
                            lock (_Channels)
                            {
                                if (channel != null)
                                {
                                    _Channels.Remove(channel);
                                }
                                if (channelKey != null)
                                {
                                    IssuedKeys.Remove(channelKey);
                                }
                            }
                            return;
                        }

                        //mark setup finish
                        setupFinished = true;

                        //call event
                        OnNewChannel?.Invoke(this, channel);

                        //start heartbeat
                        channel.Start();
                    }
                    catch (Exception ex)
                    {
                        DebugEx.Assert(ex, "YPServer: Failed setting up new connection for " + channel);
#if NETFX
                        try { newsocket.Close(); } catch { }
#endif
                        try { newsocket.Dispose(); } catch { }

                        //remove from lookups
                        lock (_Channels)
                        {
                            if (channel != null)
                            {
                                _Channels.Remove(channel);
                            }
                            if (channelKey != null)
                            {
                                IssuedKeys.Remove(channelKey);
                            }
                        }
                        return;
                    }
                });
            }
            catch (Exception ex)
            {
                DebugEx.Assert(ex, "YPChannel server setup new connection error");
            }
        }
Beispiel #10
0
        //------------------------------------------------------------------------------------------------------------------------
        private void Discoverer_OnEndpointMsgRx(YPChannel.Transport.Sockets.LANDiscoverer.RemoteEndpointInfo endpoint, YPChannel.Transport.Sockets.IDiscoveryMessageBase __msg)
        {
            try
            {
                //get valid msg
                var msg = __msg as DiscoveryMessage;
                if (msg == null)
                {
                    return;
                }

                //create remotenodekey
                var rem_nodekey = API.Plegma.NodeKey.FromBytes(msg.NodeKey, 0);
                if (rem_nodekey.IsInvalid)
                {
                    return;
                }

                //examine existing association
                lock (RemoteNodes)
                {
                    var remInfo = RemoteNodes.TryGetOrDefault(endpoint.ID);
                    if (remInfo == null)
                    {
                        //inform
                        DebugEx.TraceLog($"NodeDiscoverer : Discovered new node. (ip:{endpoint.IPAddress} nodekey:{rem_nodekey})");

                        //create entry for remote node
                        remInfo = new RemoteNode(Node, TimeSpan.FromMinutes(5), this)
                        {
                            RemoteEndpointID = endpoint.ID,
                            DiscoveryMessage = msg,
                            RemoteNodeKey    = rem_nodekey,
                        };
                        //add to discovered remote nodes
                        RemoteNodes.Add(endpoint.ID, remInfo);

                        //hookevents
                        hookNewRemoteNodeEvents(remInfo);

                        //Start a connection attempt
                        remInfo.StartConnectionTask();

                        //raise event
                        if (OnRemoteNodeDiscovery != null)
                        {
                            Task.Run(() => { try { OnRemoteNodeDiscovery?.Invoke(remInfo); } catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception"); } });
                        }
                    }
                    else
                    {
                        //start remote node connection
                        if (!remInfo.IsDisposed &&
                            (remInfo.ClientChannel == null || (remInfo.ClientChannel.State == YPChannel.ChannelStates.Closed && !remInfo.ConnectionTaskRunning)))
                        {
                            remInfo.StartConnectionTask();
                        }
                    }
                }
            }
            catch (Exception ex) { DebugEx.TraceError(ex, "DiscoveryTaskEntryPoint error"); }
        }