//------------------------------------------------------------------------------------------------------------------------ private void RemoteNode_OnChannelClose(RemoteNode RemoteNode) { if (!RemoteNode.IsConnected) { BrotherNodes.Remove(RemoteNode.RemoteNodeKey); } }
private void _channelDisconnected(ButtonConnectionChannel channel) { var bdAddr = channel.BdAddr; DebugEx.TraceLog(channel.ToString() + " disconnected"); ButtonChannels.Remove(bdAddr); }
//------------------------------------------------------------------------------------------------------------------------ void CleanUp() { foreach (var entry in DiscoveredEndpoints) { if ((DateTime.Now - entry.Value.LastMessageTimestamp) > EndpointTimeout) { DiscoveredEndpoints.Remove(entry.Key); OnEndpointTimeout?.Invoke(entry.Value); } } }
//------------------------------------------------------------------------------------------------------------------------ private void Discoverer_OnEndpointTimeout(LANDiscoverer.RemoteEndpointInfo endpoint) { try { var remInfo = RemoteNodes.TryGetOrDefault(endpoint.ID); if (remInfo != null) { remInfo._disconnect(); RemoteNodes.Remove(endpoint.ID); } } catch (Exception ex) { DebugEx.TraceError(ex, "Discoverer_OnEndpointTimeout error"); } }
//------------------------------------------------------------------------------------------------------------------------ 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); }
//------------------------------------------------------------------------------------------------------------------------ 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); } }
//------------------------------------------------------------------------------------------------------------------------ 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"); } }