コード例 #1
0
ファイル: iOSSocketWorker.cs プロジェクト: xhowar/KittyHawkMQ
        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);
        }
コード例 #2
0
 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);
 }
コード例 #3
0
        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();
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
ファイル: iOSSocketWorker.cs プロジェクト: xhowar/KittyHawkMQ
        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);
            }
        }
コード例 #6
0
ファイル: iOSSocketWorker.cs プロジェクト: xhowar/KittyHawkMQ
        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");
                }
            };
        }
コード例 #7
0
ファイル: iOSSocketWorker.cs プロジェクト: xhowar/KittyHawkMQ
        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);
                }
            });
        }
コード例 #8
0
        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();
            }
        }
コード例 #9
0
        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);
            }
        }
コード例 #10
0
 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;
 }
コード例 #11
0
        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);
                }
            });
        }
コード例 #12
0
        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);
            }
        }