private NSOutputStream GetStreamForConnectionConext(SocketEventArgs args) { NSOutputStream stream; lock (_connectedClients) { if (!_connectedClients.ContainsKey(args.ClientUid)) { args.SocketException = new InvalidOperationException("No remote connection has been established."); args.Complete(); return(null); } ConnectedClientInfo info = _connectedClients[args.ClientUid]; try { stream = info.Stream.Output; } catch (Exception ex) { args.SocketException = ex; args.Complete(); return(null); } } return(stream); }
private Stream GetStreamForConnection(ConnectedClientInfo info) { if (info.Stream == null) { lock (info) { if (info.Stream == null) { info.Stream = _getStreamHandler(info.TcpClient, info.Encryption); } } } return(info.Stream); }
private void ClientReceiverThreadProc() { _tokenSource = new CancellationTokenSource(); var token = _tokenSource.Token; var receiverThread = new Thread(() => { _logger.LogMessage("Socket", LogLevel.Verbose, "Starting receiver thread loop."); while (true) { try { ConnectedClientInfo info = GetNextClient(); if (info != null) { PollClient(info, token); } if (_tokenSource.IsCancellationRequested) { throw new TaskCanceledException(); } // Give up time slice before looping Thread.Sleep(MqttProtocolInformation.InternalSettings.SocketReceiverThreadLoopDelay); } catch (ObjectDisposedException) { // Socket or stream closed underneath us because client disconnected. Just ignore _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Network receiver thread is terminating due to ObjectDisposedException.")); return; } catch (TaskCanceledException) { _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Network receiver thread is terminating due to cancellation request.")); return; } catch (Exception ex) { ProcessException(ex); } } }); receiverThread.Start(); }
private void PollClient(ConnectedClientInfo info, CancellationToken token) { TcpClient tcpClient = info.TcpClient; byte[] buffer = null; if (tcpClient.Available > 0) { Stream stream = GetStreamForConnection(info); buffer = ReadFromInputStreamAsync(stream, info.ClientUid, token); } if (buffer != null && buffer.Length > 0) { ProcessBuffer(buffer, info); } }
public void ConnectTcpClient(NSStreamPair streams, int port, SocketEncryption encryption, string connectionKey) { var encryptionLevel = SslProtocols.None; switch (encryption) { case SocketEncryption.None: encryptionLevel = SslProtocols.None; break; case SocketEncryption.Ssl: encryptionLevel = SslProtocols.Ssl3; break; case SocketEncryption.Tls10: encryptionLevel = SslProtocols.Tls; break; case SocketEncryption.Tls11: encryptionLevel = SslProtocols.Tls11; break; case SocketEncryption.Tls12: encryptionLevel = SslProtocols.Tls12; break; } lock (_connectedClients) { _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Adding new TCP client: key={0}", connectionKey)); var clientInfo = new ConnectedClientInfo { //Socket = socket, Stream = streams, Port = port, Encryption = encryptionLevel, ClientUid = connectionKey }; _connectedClients.Add(connectionKey, clientInfo); ListeningInputStream(clientInfo); } }
private void ListeningInputStream(ConnectedClientInfo info) { NSInputStream stream = info.Stream.Input; stream.OnEvent += (_, e) => { if (e.StreamEvent == NSStreamEvent.HasBytesAvailable) { var buffer = ReadFromInputStream(stream, info.ClientUid); if (buffer != null && buffer.Length > 0) { ProcessBuffer(buffer, info); } } else if (e.StreamEvent == NSStreamEvent.ErrorOccurred) { _logger.LogMessage("Socket", LogLevel.Error, "Some error occured within the input stream"); } }; }
private void ProcessBuffer(byte[] buffer, ConnectedClientInfo info) { ThreadPool.QueueUserWorkItem(state => { // When receiving the ConnAck message, we are still using the ConnectionKey param // All other cases we've connected the client and use the ClientUid param var args = new MqttNetEventArgs { ClientUid = info.ClientUid }; try { // Process incomming messages args.Message = MqttMessageDeserializer.Deserialize(buffer); if (args.Message is IMqttIdMessage) { var msgWithId = args.Message as IMqttIdMessage; _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Received message type '{0}', ID={1}, from client {2}.", msgWithId.MessageType, msgWithId.MessageId, info.ClientUid)); } else { _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Received message type '{0}' from client {1}.", args.Message.MessageType, info.ClientUid)); } } catch (Exception ex) { var outer = new Exception(string.Format("Error deserializing message from network buffer. Buffer may be corrupt. Details: {0}", ex.Message), ex); args.Exception = outer; _logger.LogMessage("Socket", LogLevel.Error, outer.Message); } if (_messageReceivedHandler != null) { _messageReceivedHandler(args); } }); }
public void Disconnect(string clientUid) { ConnectedClientInfo clientInfo = null; lock (_connectedClients) { if (_connectedClients.ContainsKey(clientUid)) { clientInfo = _connectedClients[clientUid]; _connectedClients.Remove(clientUid); } } if (clientInfo != null) { if (clientInfo.Stream != null) { clientInfo.Stream.Close(); } clientInfo.TcpClient.Close(); clientInfo.Dispose(); } }
private ConnectedClientInfo GetNextClient() { lock (_connectedClients) { //DateTime now = DateTime.Now; //if (now.Second == 0 && now.Millisecond < 20) //{ // _logger.LogMessage("Socket", LogLevel.Verbose, "Number of live connections=" + _connectedClients.Count); //} if (_connectedClients.Count == 0) { return(null); } if (_nextCollectionIndex >= _connectedClients.Count) { _nextCollectionIndex = 0; } ConnectedClientInfo info = _connectedClients.Values.ElementAt(_nextCollectionIndex); _nextCollectionIndex++; return(info); } }
private Stream GetStreamForConnection(ConnectedClientInfo info) { if (info.Stream == null) { lock (info) { if (info.Stream == null) { info.Stream = _getStreamHandler(info.TcpClient, info.Encryption); } } } return info.Stream; }
private void ProcessBuffer(byte[] buffer, ConnectedClientInfo info) { ThreadPool.QueueUserWorkItem(state => { // When receiving the ConnAck message, we are still using the ConnectionKey param // All other cases we've connected the client and use the ClientUid param var args = new MqttNetEventArgs { ClientUid = info.ClientUid }; try { // Process incomming messages args.Message = MqttMessageDeserializer.Deserialize(buffer); if (args.Message is IMqttIdMessage) { var msgWithId = args.Message as IMqttIdMessage; _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Received message type '{0}', ID={1}, from client {2}.", msgWithId.MessageType, msgWithId.MessageId, info.ClientUid)); } else { _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Received message type '{0}' from client {1}.", args.Message.MessageType, info.ClientUid)); } } catch (Exception ex) { var outer = new Exception(string.Format("Error deserializing message from network buffer. Buffer may be corrupt. Details: {0}", ex.Message), ex); args.Exception = outer; _logger.LogMessage("Socket", LogLevel.Error, outer.Message); } if (_messageReceivedHandler != null) { _messageReceivedHandler(args); } }); }
private void PollClient(ConnectedClientInfo info, CancellationToken token) { TcpClient tcpClient = info.TcpClient; byte[] buffer = null; if (tcpClient.Available > 0) { Stream stream = GetStreamForConnection(info); buffer = ReadFromInputStreamAsync(stream, info.ClientUid, token); } if (buffer != null && buffer.Length > 0) { ProcessBuffer(buffer, info); } }