/// <summary> /// Send byte data to a peer and await a response. /// </summary> /// <param name="peer">Peer IP address.</param> /// <param name="data">Peer port number.</param> /// <param name="response">Byte data returned by the peer.</param> /// <returns>True if successful.</returns> public bool SendSync(string ip, int port, int timeoutMs, byte[] data, out byte[] response) { response = null; if (String.IsNullOrEmpty(ip)) { throw new ArgumentNullException(nameof(ip)); } if (port < 0) { throw new ArgumentException("Port must be zero or greater."); } if (timeoutMs < 1) { throw new ArgumentException("Timeout must be zero or greater."); } if (data == null || data.Length < 1) { throw new ArgumentNullException(nameof(data)); } MeshClient currClient = GetMeshClientByIpPort(ip, port); if (currClient == null || currClient == default(MeshClient)) { return(false); } return(SendSyncRequestInternal(currClient, MessageType.Data, timeoutMs, data, out response)); }
/// <summary> /// Send byte data to a peer asynchronously using a stream. /// </summary> /// <param name="ip">Peer IP address.</param> /// <param name="port">Peer port number.</param> /// <param name="contentLength">The number of bytes to read from the stream.</param> /// <param name="stream">The stream containing the data.</param> /// <returns>True if successful.</returns> public bool SendAsync(string ip, int port, long contentLength, Stream stream) { if (String.IsNullOrEmpty(ip)) { throw new ArgumentNullException(nameof(ip)); } if (port < 0) { throw new ArgumentException("Port must be zero or greater."); } if (contentLength < 1) { throw new ArgumentException("Content length must be at least one byte."); } if (stream == null || !stream.CanRead) { throw new ArgumentException("Cannot read from supplied stream."); } MeshClient currClient = GetMeshClientByIpPort(ip, port); if (currClient == null || currClient == default(MeshClient)) { return(false); } return(SendAsyncInternal(currClient, MessageType.Data, contentLength, stream)); }
/// <summary> /// Remove a peer from the network. /// </summary> /// <param name="peer">Peer.</param> public void Remove(Peer peer) { if (peer == null) { throw new ArgumentNullException(nameof(peer)); } lock (_PeerLock) { Peer currPeer = _Peers.Where(p => p.Ip.Equals(peer.Ip) && p.Port.Equals(peer.Port)).FirstOrDefault(); if (currPeer == null || currPeer == default(Peer)) { } else { _Peers.Remove(currPeer); } } lock (_ClientsLock) { MeshClient currClient = _Clients.Where(c => c.Peer.Ip.Equals(peer.Ip) && c.Peer.Port.Equals(peer.Port)).FirstOrDefault(); if (currClient == null || currClient == default(MeshClient)) { } else { currClient.Dispose(); _Clients.Remove(currClient); } } }
private bool MeshServerMessageReceived(string ipPort, byte[] data) { try { Message currMsg = new Message(data, true); // Console.WriteLine(currMsg.ToString()); Peer currPeer = GetPeerByIpPort(currMsg.SourceIp, currMsg.SourcePort); if (currPeer == null || currPeer == default(Peer)) { // Console.WriteLine("Unable to find peer " + currMsg.SourceIp + ":" + currMsg.SourcePort); return(false); } if (currMsg.SyncRequest) { if (SyncMessageReceived != null) { SyncResponse syncResponse = SyncMessageReceived(currPeer, currMsg.Data); Message responseMsg = new Message(_Self.Ip, _Self.Port, currPeer.Ip, currPeer.Port, currMsg.TimeoutMs, false, true, currMsg.Type, syncResponse.Data); responseMsg.Id = currMsg.Id; MeshClient currClient = GetMeshClientByIpPort(currPeer.Ip, currPeer.Port); return(SendSyncResponseInternal(currClient, responseMsg)); } } else if (currMsg.SyncResponse) { // add to sync responses PendingResponse pendingResp = new PendingResponse(DateTime.Now.AddMilliseconds(currMsg.TimeoutMs), currMsg); _PendingResponses.TryAdd(currMsg.Id, pendingResp); return(true); } else { if (AsyncMessageReceived != null) { return(AsyncMessageReceived(currPeer, currMsg.Data)); } } return(true); } catch (Exception e) { Console.WriteLine("ClientMessageReceived exception: " + Environment.NewLine + Common.SerializeJson(e, true)); return(false); } }
private bool SendAsyncInternal(MeshClient client, MessageType msgType, long contentLength, Stream stream) { try { Message msg = new Message(_Self.Ip, _Self.Port, client.Peer.Ip, client.Peer.Port, 0, false, false, msgType, contentLength, stream); byte[] msgData = msg.ToBytes(); return(client.Send(msgData).Result); } catch (Exception e) { if (_Settings.Debug) { Console.WriteLine(Common.SerializeJson(e, true)); } return(false); } }
private bool SendAsyncInternal(MeshClient client, MessageType msgType, byte[] data) { try { Message msg = new Message(_Self.Ip, _Self.Port, client.Peer.Ip, client.Peer.Port, 0, false, false, msgType, data); byte[] msgData = msg.ToBytes(); return(client.Send(msgData).Result); } catch (Exception e) { if (_Settings.Debug) { Console.WriteLine("SendAsyncInternal Exception " + Environment.NewLine + Common.SerializeJson(e, true)); } return(false); } }
/// <summary> /// Check if a specific remote server connection is alive. /// </summary> /// <param name="ip">Peer IP address.</param> /// <param name="port">Peer port number.</param> /// <returns>True if healthy.</returns> public bool IsHealthy(string ip, int port) { if (String.IsNullOrEmpty(ip)) { throw new ArgumentNullException(nameof(ip)); } if (port < 0) { throw new ArgumentException("Port must be zero or greater."); } MeshClient currClient = GetMeshClientByIpPort(ip, port); if (currClient == null) { return(false); } return(currClient.Connected); }
private bool MeshClientStreamReceived(Peer peer, long contentLength, Stream stream) { try { Message currMsg = new Message(stream, _Settings.ReadStreamBufferSize); if (currMsg.SyncRequest) { if (SyncMessageReceived != null) { SyncResponse syncResponse = SyncStreamReceived(peer, currMsg.ContentLength, currMsg.DataStream); Console.WriteLine("ServerStreamReceived received sync response"); Message responseMsg = new Message(_Self.Ip, _Self.Port, peer.Ip, peer.Port, currMsg.TimeoutMs, false, true, currMsg.Type, syncResponse.Data); Console.WriteLine("ServerStreamReceived built message"); responseMsg.Id = currMsg.Id; MeshClient currClient = GetMeshClientByIpPort(peer.Ip, peer.Port); return(SendSyncResponseInternal(currClient, responseMsg)); } } else if (currMsg.SyncResponse) { // add to sync responses PendingResponse pendingResp = new PendingResponse(DateTime.Now.AddMilliseconds(currMsg.TimeoutMs), currMsg); _PendingResponses.TryAdd(currMsg.Id, pendingResp); } else { if (AsyncStreamReceived != null) { return(AsyncStreamReceived(peer, currMsg.ContentLength, currMsg.DataStream)); } } return(true); } catch (Exception e) { Console.WriteLine("ServerStreamReceived exception: " + Environment.NewLine + Common.SerializeJson(e, true)); return(false); } }
private MeshClient GetMeshClientByIpPort(string ip, int port) { if (String.IsNullOrEmpty(ip)) { throw new ArgumentNullException(nameof(ip)); } if (port < 0) { throw new ArgumentException("Port must be zero or greater."); } lock (_ClientsLock) { MeshClient currClient = _Clients.Where(c => c.Peer.Ip.Equals(ip) && c.Peer.Port.Equals(port)).FirstOrDefault(); if (currClient == null || currClient == default(MeshClient)) { return(null); } return(currClient); } }
/// <summary> /// Add a peer to the network. /// </summary> /// <param name="peer">Peer.</param> public void Add(Peer peer) { if (peer == null) { throw new ArgumentNullException(nameof(peer)); } lock (_PeerLock) { bool exists = _Peers.Any(p => p.Ip.Equals(peer.Ip) && p.Port.Equals(peer.Port)); if (exists) { _Peers = _Peers.Where(p => !p.Ip.Equals(peer.Ip) && !p.Port.Equals(peer.Port)).ToList(); } _Peers.Add(peer); } lock (_ClientsLock) { bool exists = _Clients.Any(c => c.Peer.Ip.Equals(peer.Ip) && c.Peer.Port.Equals(peer.Port)); if (exists) { return; } else { MeshClient currClient = new MeshClient(_Settings, peer); currClient.ServerConnected = MeshClientServerConnected; currClient.ServerDisconnected = MeshClientServerDisconnected; currClient.MessageReceived = MeshClientMessageReceived; currClient.StreamReceived = MeshClientStreamReceived; Task.Run(() => currClient.Start()); _Clients.Add(currClient); } } }
/// <summary> /// Send byte data to a peer asynchronously. /// </summary> /// <param name="ip">Peer IP address.</param> /// <param name="port">Peer port number.</param> /// <param name="data">Byte data to send.</param> /// <returns>True if successful.</returns> public bool SendAsync(string ip, int port, byte[] data) { if (String.IsNullOrEmpty(ip)) { throw new ArgumentNullException(nameof(ip)); } if (port < 0) { throw new ArgumentException("Port must be zero or greater."); } if (data == null || data.Length < 1) { throw new ArgumentNullException(nameof(data)); } MeshClient currClient = GetMeshClientByIpPort(ip, port); if (currClient == null || currClient == default(MeshClient)) { return(false); } return(SendAsyncInternal(currClient, MessageType.Data, data)); }
private bool SendSyncRequestInternal(MeshClient client, MessageType msgType, int timeoutMs, byte[] data, out byte[] response) { response = null; Message msg = new Message(_Self.Ip, _Self.Port, client.Peer.Ip, client.Peer.Port, timeoutMs, true, false, msgType, data); byte[] msgData = msg.ToBytes(); try { if (!AddSyncRequest(msg.Id, timeoutMs)) { return(false); } if (!client.Send(msgData).Result) { return(false); } return(GetSyncResponse(msg.Id, timeoutMs, out response)); } catch (Exception e) { if (_Settings.Debug) { Console.WriteLine(Common.SerializeJson(e, true)); } return(false); } finally { DateTime ts; if (_SyncRequests.ContainsKey(msg.Id)) { _SyncRequests.TryRemove(msg.Id, out ts); } } }
private bool SendSyncResponseInternal(MeshClient client, Message msg) { byte[] msgData = msg.ToBytes(); return(client.Send(msgData).Result); }