コード例 #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
        public void ConnectAsync(MqttConnectMessageBuilder bldr, string ipOrHost, int port, SocketEncryption encryption, object eventData)
        {
            var args = new SocketEventArgs
            {
                EncryptionLevel = encryption,
                ClientUid = GenerateClientUid(bldr)
            };

            args.OnOperationComplete((eventArgs) =>
            {
                OnTcpConnectAsyncCompleted(eventArgs, eventData);

                if (eventArgs.SocketException == null)
                {
                    SendMessageAsync(bldr, eventData, eventArgs.ClientUid);
                }
                else
                {
                    FireConnectComplete(new MqttNetEventArgs
                    {
                        Message = bldr.GetMessage(),
                        Exception = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData = eventData,
                        ClientUid = args.ClientUid
                    });
                }
            });

            Socket.ConnectAsync(ipOrHost, port, args);
        }
コード例 #3
0
        public void ConnectAsync(MqttConnectMessageBuilder bldr, string ipOrHost, int port, SocketEncryption encryption, object eventData)
        {
            var args = new SocketEventArgs
            {
                EncryptionLevel = encryption,
                ClientUid       = GenerateClientUid(bldr)
            };

            args.OnOperationComplete((eventArgs) =>
            {
                OnTcpConnectAsyncCompleted(eventArgs, eventData);

                if (eventArgs.SocketException == null)
                {
                    SendMessageAsync(bldr, eventData, eventArgs.ClientUid);
                }
                else
                {
                    FireConnectComplete(new MqttNetEventArgs
                    {
                        Message             = bldr.GetMessage(),
                        Exception           = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData           = eventData,
                        ClientUid           = args.ClientUid
                    });
                }
            });

            Socket.ConnectAsync(ipOrHost, port, args);
        }
コード例 #4
0
        public async void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            _socket = new StreamSocket();
            var server = new HostName(ipOrHost);

            // TCP timeouts in WinRT are excessive, shorten them here using task cancellation
            var cts = new CancellationTokenSource();

            try
            {
                cts.CancelAfter(MqttProtocolInformation.Settings.NetworkTimeout * 1000);
                _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Authenticating client certificate with remote host CN={0}", server.CanonicalName));
                await _socket.ConnectAsync(server, port.ToString(), GetSocketProtectionLevel(args.EncryptionLevel)).AsTask(cts.Token);
                _clientUid = args.ClientUid;
                StartReceiving();
            }
            catch (TaskCanceledException)
            {
                args.SocketException = new IOException("Timeout error while trying to connect.");
                _clientUid = null;
                _socket.Dispose();
                _socket = null;
            }
            catch (Exception ex)
            {
                args.SocketException = ex;
                _clientUid = null;
                _socket.Dispose();
                _socket = null;
            }
            args.Complete();
        }
コード例 #5
0
        public async void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            _socket = new StreamSocket();
            var server = new HostName(ipOrHost);

            // TCP timeouts in WinRT are excessive, shorten them here using task cancellation
            var cts = new CancellationTokenSource();

            try
            {
                cts.CancelAfter(MqttProtocolInformation.Settings.NetworkTimeout * 1000);
                _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Authenticating client certificate with remote host CN={0}", server.CanonicalName));
                await _socket.ConnectAsync(server, port.ToString(), GetSocketProtectionLevel(args.EncryptionLevel)).AsTask(cts.Token);

                _clientUid = args.ClientUid;
                StartReceiving();
            }
            catch (TaskCanceledException)
            {
                args.SocketException = new IOException("Timeout error while trying to connect.");
                _clientUid           = null;
                _socket.Dispose();
                _socket = null;
            }
            catch (Exception ex)
            {
                args.SocketException = ex;
                _clientUid           = null;
                _socket.Dispose();
                _socket = null;
            }
            args.Complete();
        }
コード例 #6
0
ファイル: iOSSocketWorker.cs プロジェクト: xhowar/KittyHawkMQ
        private void WriteAsyncInternal(NSOutputStream stream, SocketEventArgs args)
        {
            byte[] sendBuffer = args.MessageToSend.Serialize();

            EventHandler <NSStreamEventArgs> completedHandler = null;

            completedHandler = (sender, e) =>
            {
                stream.OnEvent -= completedHandler;

                if (args.MessageToSend is IMqttIdMessage)
                {
                    var msgWithId = args.MessageToSend as IMqttIdMessage;
                    _logger.LogMessage("Socket", LogLevel.Verbose,
                                       string.Format("Sent message type '{0}', ID={1}.", msgWithId.MessageType,
                                                     msgWithId.MessageId));
                }
                else
                {
                    _logger.LogMessage("Socket", LogLevel.Verbose,
                                       string.Format("Sent message type '{0}'.", args.MessageToSend.MessageType));
                }

                if (e.StreamEvent == NSStreamEvent.ErrorOccurred)
                {
                    args.SocketException = new Exception("Socket error occured: " + e.StreamEvent.ToString());
                }

                args.Complete();
            };

            stream.OnEvent += completedHandler;
            stream.Write(sendBuffer, (nuint)sendBuffer.Length);
        }
コード例 #7
0
 protected override void OnTcpConnectAsyncCompleted(SocketEventArgs eventArgs, object eventData)
 {
     if (eventArgs.SocketException == null)
     {
         _clientUid = eventArgs.ClientUid;
         // In case the client changed global settings, refresh the timeouts on every connect
         _keepAliveTimer.Reset(MqttProtocolInformation.Settings.KeepAliveTime);
     }
 }
コード例 #8
0
 public SocketEventArgs Clone()
 {
     var arg = new SocketEventArgs();
     arg._completedHandler = _completedHandler;
     arg.SocketException = SocketException;
     arg.MessageToSend = MessageToSend;
     arg.AdditionalErrorInfo = AdditionalErrorInfo;
     arg.ClientUid = ClientUid;
     arg.EncryptionLevel = EncryptionLevel;
     return arg;
 }
コード例 #9
0
        public SocketEventArgs Clone()
        {
            var arg = new SocketEventArgs();

            arg._completedHandler   = _completedHandler;
            arg.SocketException     = SocketException;
            arg.MessageToSend       = MessageToSend;
            arg.AdditionalErrorInfo = AdditionalErrorInfo;
            arg.ClientUid           = ClientUid;
            arg.EncryptionLevel     = EncryptionLevel;
            return(arg);
        }
コード例 #10
0
ファイル: iOSSocketWorker.cs プロジェクト: xhowar/KittyHawkMQ
        public void WriteAsync(SocketEventArgs args)
        {
            NSOutputStream stream = GetStreamForConnectionConext(args);

            if (stream == null)
            {
                // OnCompleted called in GetStreamForConnectionConext(), just return here.
                return;
            }

            try
            {
                EventHandler <NSStreamEventArgs> handler = null;
                handler = (_, e1) =>
                {
                    stream.OnEvent -= handler;

                    if (e1.StreamEvent == NSStreamEvent.ErrorOccurred)
                    {
                        args.SocketException = new Exception("Something unexpected happened. " + e1.StreamEvent.ToString());
                        args.Complete();
                    }

                    if (e1.StreamEvent != NSStreamEvent.HasSpaceAvailable)
                    {
                        return;
                    }

                    WriteAsyncInternal(stream, args);
                };

                if (stream.HasSpaceAvailable())
                {
                    WriteAsyncInternal(stream, args);
                }
                else
                {
                    stream.OnEvent += handler;
                }
            }
            catch (ObjectDisposedException)
            {
                // Effectively ignoring this
                args.Complete();
            }
            catch (Exception ex)
            {
                args.SocketException =
                    new Exception("Unable to write to the TCP connection. See inner exception for details.", ex);
                args.Complete();
            }
        }
コード例 #11
0
        public void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            var t = new Thread(() =>
            {
                IPEndPoint ep;
                try
                {
                    ep = ResolveIpAddress(ipOrHost, port);
                }
                catch (Exception ex)
                {
                    args.SocketException = ex;
                    args.AdditionalErrorInfo = "Unable to resolve ip address or host name.";
                    args.Complete();
                    return;
                }

                _encryptionLevel = GetSslProtocol(args.EncryptionLevel);
                _clientUid = args.ClientUid;

                try
                {
                    CreateSocketAndConnect(ep);
                    StartReceiving();
                }
                catch (Exception ex)
                {
                    _clientUid = null;
                    args.SocketException = ex;
                }
                finally
                {
                    args.Complete();
                }
            });

            // Start the writer thread
            _writerThread = new Thread(WriteMessageWorker);
            _writerThread.Start();

            // Go connect
            t.Start();
        }
コード例 #12
0
        public void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            var t = new Thread(() =>
            {
                IPEndPoint ep;
                try
                {
                    ep = ResolveIpAddress(ipOrHost, port);
                }
                catch (Exception ex)
                {
                    args.SocketException     = ex;
                    args.AdditionalErrorInfo = "Unable to resolve ip address or host name.";
                    args.Complete();
                    return;
                }

                _encryptionLevel = GetSslProtocol(args.EncryptionLevel);
                _clientUid       = args.ClientUid;

                try
                {
                    CreateSocketAndConnect(ep);
                    StartReceiving();
                }
                catch (Exception ex)
                {
                    _clientUid           = null;
                    args.SocketException = ex;
                }
                finally
                {
                    args.Complete();
                }
            });

            // Start the writer thread
            _writerThread = new Thread(WriteMessageWorker);
            _writerThread.Start();

            // Go connect
            t.Start();
        }
コード例 #13
0
        public void WriteAsync(SocketEventArgs args)
        {
            if (_socket == null)
            {
                args.SocketException = new InvalidOperationException("No server connection has been established.");
                args.Complete();
                return;
            }

            try
            {
                // Write data to the socket
                var writer = new DataWriter(_socket.OutputStream);
                writer.WriteBytes(args.MessageToSend.Serialize());
                writer.StoreAsync().Completed += (info, status) =>
                {
                    writer.DetachStream();
                    writer.Dispose();

                    if (args.MessageToSend is IMqttIdMessage)
                    {
                        var msgWithId = args.MessageToSend as IMqttIdMessage;
                        _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Sent message type '{0}', ID={1} to server.", msgWithId.MessageType, msgWithId.MessageId));
                    }
                    else
                    {
                        _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Sent message type '{0}' to server.", args.MessageToSend.MessageType));
                    }

                    if (info.Status == AsyncStatus.Error)
                    {
                        args.SocketException = info.ErrorCode;
                    }
                    args.Complete();
                };
            }
            catch (Exception ex)
            {
                args.SocketException = ex;
                args.Complete();
            }
        }
コード例 #14
0
        public void WriteAsync(SocketEventArgs args)
        {
            if (_socket == null)
            {
                args.SocketException = new InvalidOperationException("No server connection has been established.");
                args.Complete();
                return;
            }

            try
            {
                // Write data to the socket
                var writer = new DataWriter(_socket.OutputStream);
                writer.WriteBytes(args.MessageToSend.Serialize());
                writer.StoreAsync().Completed += (info, status) =>
                {
                    writer.DetachStream();
                    writer.Dispose();

                    if (args.MessageToSend is IMqttIdMessage)
                    {
                        var msgWithId = args.MessageToSend as IMqttIdMessage;
                        _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Sent message type '{0}', ID={1} to server.", msgWithId.MessageType, msgWithId.MessageId));
                    }
                    else
                    {
                        _logger.LogMessage("Socket", LogLevel.Verbose, string.Format("Sent message type '{0}' to server.", args.MessageToSend.MessageType));
                    }

                    if (info.Status == AsyncStatus.Error)
                    {
                        args.SocketException = info.ErrorCode;
                    }
                    args.Complete();
                };
            }
            catch (Exception ex)
            {
                args.SocketException = ex;
                args.Complete();
            }
        }
コード例 #15
0
        public async void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            TcpClient tcpClient;
            IPAddress ip;
            Task connectTask;

            if (IPAddress.TryParse(ipOrHost, out ip))
            {
                _remoteHost = "";
                var endPoint = new IPEndPoint(ip, port);
                tcpClient = CreateSocket(endPoint.AddressFamily);
                connectTask = tcpClient.ConnectAsync(endPoint.Address, port);
            }
            else
            {
                _remoteHost = ipOrHost;
                tcpClient = CreateSocket(AddressFamily.Unspecified);
                connectTask = tcpClient.ConnectAsync(ipOrHost, port);
            }

            await connectTask.ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    if (task.Exception != null && task.Exception.InnerExceptions.Count > 0)
                    {
                        args.SocketException = task.Exception.InnerExceptions[0];
                    }
                    else
                    {
                        args.SocketException = new Exception("Unknown socket error.");
                    }
                }
                else
                {
                    _socketWorker.ConnectTcpClient(tcpClient, port, args.EncryptionLevel, args.ClientUid);
                }
                args.Complete();
            });
        }
コード例 #16
0
        public async void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            TcpClient tcpClient;
            IPAddress ip;
            Task      connectTask;

            if (IPAddress.TryParse(ipOrHost, out ip))
            {
                _remoteHost = "";
                var endPoint = new IPEndPoint(ip, port);
                tcpClient   = CreateSocket(endPoint.AddressFamily);
                connectTask = tcpClient.ConnectAsync(endPoint.Address, port);
            }
            else
            {
                _remoteHost = ipOrHost;
                tcpClient   = CreateSocket(AddressFamily.Unspecified);
                connectTask = tcpClient.ConnectAsync(ipOrHost, port);
            }

            await connectTask.ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    if (task.Exception != null && task.Exception.InnerExceptions.Count > 0)
                    {
                        args.SocketException = task.Exception.InnerExceptions[0];
                    }
                    else
                    {
                        args.SocketException = new Exception("Unknown socket error.");
                    }
                }
                else
                {
                    _socketWorker.ConnectTcpClient(tcpClient, port, args.EncryptionLevel, args.ClientUid);
                }
                args.Complete();
            });
        }
コード例 #17
0
        public void WriteAsync(SocketEventArgs args)
        {
            if (_socket == null)
            {
                args.SocketException = new InvalidOperationException("No server connection has been established.");
                FireOnCompletedNewThread(args);
                return;
            }

            int waitResult = WaitHandle.WaitAny(new WaitHandle[] { _stopEvent, _writerThreadReady },
                                                MqttProtocolInformation.Settings.NetworkTimeout * 1000, false);

            if (waitResult == WaitHandle.WaitTimeout || waitResult == 0)
            {
                args.SocketException = new Exception("Unable to send message type " + args.MessageToSend.MessageType + ". Client may be disconnecting.");
                FireOnCompletedNewThread(args);
                return;
            }

            _writerEventArgs = args;
            _writerThreadWrite.Set();
        }
コード例 #18
0
 /// <summary>
 /// Let derived classes handle the ConnectAsyncComplete callback.
 /// </summary>
 /// <param name="eventArgs"></param>
 /// <param name="eventData"></param>
 /// <returns></returns>
 protected virtual void OnTcpConnectAsyncCompleted(SocketEventArgs eventArgs, object eventData)
 {
 }
コード例 #19
0
 public void WriteAsync(SocketEventArgs args)
 {
     _socketWorker.WriteAsync(args);
 }
コード例 #20
0
ファイル: MoqSocket.cs プロジェクト: reicheltp/KittyHawkMQ
 public void ConnectAsync(string ipAddress, int port, SocketEventArgs args)
 {
     _isConnected = true;
     args.Complete();
 }
コード例 #21
0
ファイル: MoqSocket.cs プロジェクト: reicheltp/KittyHawkMQ
        public void WriteAsync(SocketEventArgs args)
        {
            SentMessages.Add(args.MessageToSend.MessageType);
            args.Complete();

            // Mock a server that does not send appropriate response
            if (DoNotRespond)
            {
                return;
            }

            // This section mocks the expected response behavior from an MQTT broker
            switch (args.MessageToSend.MessageType)
            {
                case MessageType.Connect:
                    var conAck = new MqttConnectAckMessageBuilder();
                    MessageReceived(new MqttNetEventArgs
                    {
                        Message = conAck.GetMessage(),
                        ClientUid = args.ClientUid
                    });
                    break;

                case MessageType.Subscribe:
                    var subMsg = args.MessageToSend as IMqttIdMessage;
                    var subAck = new MqttSubscribeAckMessageBuilder
                    {
                        MessageId = subMsg.MessageId
                   };
                    MessageReceived(new MqttNetEventArgs
                    {
                        Message = subAck.GetMessage(),
                        ClientUid = args.ClientUid
                    });
                    break;

                case MessageType.Unsubscribe:
                    var unsubMsg = args.MessageToSend as IMqttIdMessage;
                    var unsubAck = new MqttUnsubscribeAckMessageBuilder
                    {
                        MessageId = unsubMsg.MessageId
                    };
                    MessageReceived(new MqttNetEventArgs
                    {
                        Message = unsubAck.GetMessage(),
                        ClientUid = args.ClientUid
                    });
                    break;

                case MessageType.PingReq:
                    var pingResp = new MqttPingResponseMessageBuilder();
                    MessageReceived(new MqttNetEventArgs
                    {
                        Message = pingResp.GetMessage(),
                        ClientUid = args.ClientUid
                    });
                    break;

                case MessageType.Publish:
                    var publishMsg = args.MessageToSend as IMqttIdMessage;
                    // Mock publish response behavior
                    if (args.MessageToSend.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        var msgRcv = new MqttPublishAckMessageBuilder
                        {
                            MessageId = publishMsg.MessageId
                        };
                        MessageReceived(new MqttNetEventArgs
                        {
                            Message = msgRcv.GetMessage(),
                            ClientUid = args.ClientUid
                        });
                    }
                    else if (args.MessageToSend.QualityOfService == QualityOfService.ExactlyOnce)
                    {
                        var msgRcv = new MqttPublishReceivedMessageBuilder()
                        {
                            MessageId = publishMsg.MessageId
                        };
                        MessageReceived(new MqttNetEventArgs
                        {
                            Message = msgRcv.GetMessage(),
                            ClientUid = args.ClientUid
                        });
                    }
                    break;

                case MessageType.PubRec:
                    var pubRec = args.MessageToSend as IMqttIdMessage;
                    var pubRel1 = new MqttPublishReleaseMessageBuilder
                    {
                        MessageId = pubRec.MessageId
                    };
                    MessageReceived(new MqttNetEventArgs
                    {
                        Message = pubRel1.GetMessage(),
                        ClientUid = args.ClientUid
                    });
                    break;

                case MessageType.PubRel:
                    var pubRel2 = args.MessageToSend as IMqttIdMessage;
                    var pubComp = new MqttPublishCompleteMessageBuilder
                    {
                        MessageId = pubRel2.MessageId
                    };
                    MessageReceived(new MqttNetEventArgs
                    {
                        Message = pubComp.GetMessage(),
                        ClientUid = args.ClientUid
                    });
                    break;
            }
        }
コード例 #22
0
        public void SendMessageAsync(IMqttMessage msg, object eventData, string clientUid)
        {
            Logger.LogMessage("Protocol", LogLevel.Verbose, "SendMessageAsync(" + msg.MessageType + ")");

            var args = new SocketEventArgs
            {
                MessageToSend = msg,
                ClientUid = clientUid
            };

            // If we expect a response, push the event data on our stack and retrieve it with the response
            if (args.MessageToSend.ExpectedResponse != MessageType.None)
            {
                _messageStore.Add(args.MessageToSend, eventData, clientUid);
            }

            args.OnOperationComplete((eventArgs) =>
            {
                MessageType messageType = eventArgs.MessageToSend.MessageType;

                string exceptionText = eventArgs.SocketException == null
                    ? "Success."
                    : "Error: " + eventArgs.SocketException.ToString();
                Logger.LogMessage("Protocol", LogLevel.Verbose, "SendMessageAsync(" + messageType + ") completed callback. " + exceptionText);

                if (eventArgs.SocketException != null)
                {
                    // Clean up pending message queue
                    _messageStore.Remove(args.MessageToSend.ExpectedResponse, MqttMessageBase.GetMessageIdOrDefault(args.MessageToSend), clientUid);
                }

                OnSendMessageAsyncCompleted(clientUid, eventArgs.MessageToSend, eventArgs.SocketException);

                if (messageType == MessageType.Connect && eventArgs.SocketException != null)
                {
                    FireConnectComplete(new MqttNetEventArgs
                    {
                        Message = args.MessageToSend,
                        Exception = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData = eventData,
                        ClientUid = clientUid
                    });
                }
                else if (messageType == MessageType.Disconnect)
                {
                    CloseConnection(clientUid);
                    FireSendMessageComplete(new MqttNetEventArgs
                    {
                        Message = args.MessageToSend,
                        Exception = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData = eventData,
                        ClientUid = clientUid
                    });
                }
                else if (messageType == MessageType.Subscribe && eventArgs.SocketException != null)
                {
                    FireSubscribeMessageComplete(new MqttNetEventArgs
                    {
                        Message = args.MessageToSend,
                        Exception = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData = eventData,
                        ClientUid = clientUid
                    });
                }
                else if (args.MessageToSend.ExpectedResponse == MessageType.None || eventArgs.SocketException != null)
                {
                    FireSendMessageComplete(new MqttNetEventArgs
                    {
                        Message = args.MessageToSend,
                        Exception = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData = eventData,
                        ClientUid = clientUid
                    });
                }
            });

            Socket.WriteAsync(args);
        }
コード例 #23
0
        public void SendMessageAsync(IMqttMessage msg, object eventData, string clientUid)
        {
            Logger.LogMessage("Protocol", LogLevel.Verbose, "SendMessageAsync(" + msg.MessageType + ")");

            var args = new SocketEventArgs
            {
                MessageToSend = msg,
                ClientUid     = clientUid
            };

            // If we expect a response, push the event data on our stack and retrieve it with the response
            if (args.MessageToSend.ExpectedResponse != MessageType.None)
            {
                _messageStore.Add(args.MessageToSend, eventData, clientUid);
            }

            args.OnOperationComplete((eventArgs) =>
            {
                MessageType messageType = eventArgs.MessageToSend.MessageType;

                string exceptionText = eventArgs.SocketException == null
                    ? "Success."
                    : "Error: " + eventArgs.SocketException.ToString();
                Logger.LogMessage("Protocol", LogLevel.Verbose, "SendMessageAsync(" + messageType + ") completed callback. " + exceptionText);

                if (eventArgs.SocketException != null)
                {
                    // Clean up pending message queue
                    _messageStore.Remove(args.MessageToSend.ExpectedResponse, MqttMessageBase.GetMessageIdOrDefault(args.MessageToSend), clientUid);
                }

                OnSendMessageAsyncCompleted(clientUid, eventArgs.MessageToSend, eventArgs.SocketException);

                if (messageType == MessageType.Connect && eventArgs.SocketException != null)
                {
                    FireConnectComplete(new MqttNetEventArgs
                    {
                        Message             = args.MessageToSend,
                        Exception           = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData           = eventData,
                        ClientUid           = clientUid
                    });
                }
                else if (messageType == MessageType.Disconnect)
                {
                    CloseConnection(clientUid);
                    FireSendMessageComplete(new MqttNetEventArgs
                    {
                        Message             = args.MessageToSend,
                        Exception           = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData           = eventData,
                        ClientUid           = clientUid
                    });
                }
                else if (messageType == MessageType.Subscribe && eventArgs.SocketException != null)
                {
                    FireSubscribeMessageComplete(new MqttNetEventArgs
                    {
                        Message             = args.MessageToSend,
                        Exception           = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData           = eventData,
                        ClientUid           = clientUid
                    });
                }
                else if (args.MessageToSend.ExpectedResponse == MessageType.None || eventArgs.SocketException != null)
                {
                    FireSendMessageComplete(new MqttNetEventArgs
                    {
                        Message             = args.MessageToSend,
                        Exception           = eventArgs.SocketException,
                        AdditionalErrorInfo = eventArgs.AdditionalErrorInfo,
                        EventData           = eventData,
                        ClientUid           = clientUid
                    });
                }
            });

            Socket.WriteAsync(args);
        }
コード例 #24
0
 private void FireOnCompletedNewThread(SocketEventArgs args)
 {
     var t = new Thread(args.Complete);
     t.Start();
 }
コード例 #25
0
 /// <summary>
 /// Let derived classes handle the ConnectAsyncComplete callback.
 /// </summary>
 /// <param name="eventArgs"></param>
 /// <param name="eventData"></param>
 /// <returns></returns>
 protected virtual void OnTcpConnectAsyncCompleted(SocketEventArgs eventArgs, object eventData)
 {
 }
コード例 #26
0
        private void FireOnCompletedNewThread(SocketEventArgs args)
        {
            var t = new Thread(args.Complete);

            t.Start();
        }
コード例 #27
0
        public async void WriteAsync(SocketEventArgs args)
        {
            Stream stream = GetStreamForConnectionConext(args);

            if (stream == null)
            {
                // OnCompleted called in GetStreamForConnectionConext(), just return here.
                return;
            }

            // Here we are outside the lock, stream can be closed beneath us
            // Typical scenario is the client asynchronously disconnects before we're finished sending it a message.
            // For now, I'm OK with this. It's better than balling this up with locks.
            try
            {
                if (stream.CanWrite)
                {
                    byte[] sendBuffer = args.MessageToSend.Serialize();
                    await stream.WriteAsync(sendBuffer, 0, sendBuffer.Length).ContinueWith(task =>
                    {
                        stream.Flush();
                        if (args.MessageToSend is IMqttIdMessage)
                        {
                            var msgWithId = args.MessageToSend as IMqttIdMessage;
                            _logger.LogMessage("Socket", LogLevel.Verbose,
                                               string.Format("Sent message type '{0}', ID={1}.", msgWithId.MessageType,
                                                             msgWithId.MessageId));
                        }
                        else
                        {
                            _logger.LogMessage("Socket", LogLevel.Verbose,
                                               string.Format("Sent message type '{0}'.", args.MessageToSend.MessageType));
                        }
                        if (task.IsFaulted)
                        {
                            if (task.Exception != null && task.Exception.InnerExceptions.Count > 0)
                            {
                                args.SocketException = task.Exception.InnerExceptions[0];
                            }
                            else
                            {
                                args.SocketException = new Exception("Unknown socket error.");
                            }
                        }
                        args.Complete();
                    });
                }
                else
                {
                    args.SocketException = new Exception("Connection state is invalid. Please try reconnecting.");
                    args.Complete();
                }
            }
            catch (ObjectDisposedException)
            {
                // Effectively ignoring this
                args.Complete();
            }
            catch (Exception ex)
            {
                args.SocketException =
                    new Exception("Unable to write to the TCP connection. See inner exception for details.", ex);
                args.Complete();
            }
        }
コード例 #28
0
        private Stream GetStreamForConnectionConext(SocketEventArgs args)
        {
            Stream 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 = GetStreamForConnection(info);
                }
                catch (Exception ex)
                {
                    args.SocketException = ex;
                    args.Complete();
                    return null;
                }
            }
            return stream;
        }
コード例 #29
0
        public void WriteAsync(SocketEventArgs args)
        {
            if (_socket == null)
            {
                args.SocketException = new InvalidOperationException("No server connection has been established.");
                FireOnCompletedNewThread(args);
                return;
            }

            int waitResult = WaitHandle.WaitAny(new WaitHandle[] {_stopEvent, _writerThreadReady},
                MqttProtocolInformation.Settings.NetworkTimeout*1000, false);

            if (waitResult == WaitHandle.WaitTimeout || waitResult == 0)
            {
                args.SocketException = new Exception("Unable to send message type " + args.MessageToSend.MessageType + ". Client may be disconnecting.");
                FireOnCompletedNewThread(args);
                return;
            }

            _writerEventArgs = args;
            _writerThreadWrite.Set();
        }
コード例 #30
0
 public void WriteAsync(SocketEventArgs args)
 {
     _socketWorker.WriteAsync(args);
 }
コード例 #31
0
        public async void WriteAsync(SocketEventArgs args)
        {
            Stream stream = GetStreamForConnectionConext(args);

            if (stream == null)
            {
                // OnCompleted called in GetStreamForConnectionConext(), just return here.
                return;
            }

            // Here we are outside the lock, stream can be closed beneath us
            // Typical scenario is the client asynchronously disconnects before we're finished sending it a message.
            // For now, I'm OK with this. It's better than balling this up with locks.
            try
            {
                if (stream.CanWrite)
                {
                    byte[] sendBuffer = args.MessageToSend.Serialize();
                    await stream.WriteAsync(sendBuffer, 0, sendBuffer.Length).ContinueWith(task =>
                    {
                        stream.Flush();
                        if (args.MessageToSend is IMqttIdMessage)
                        {
                            var msgWithId = args.MessageToSend as IMqttIdMessage;
                            _logger.LogMessage("Socket", LogLevel.Verbose,
                                string.Format("Sent message type '{0}', ID={1}.", msgWithId.MessageType,
                                    msgWithId.MessageId));
                        }
                        else
                        {
                            _logger.LogMessage("Socket", LogLevel.Verbose,
                                string.Format("Sent message type '{0}'.", args.MessageToSend.MessageType));
                        }
                        if (task.IsFaulted)
                        {
                            if (task.Exception != null && task.Exception.InnerExceptions.Count > 0)
                            {
                                args.SocketException = task.Exception.InnerExceptions[0];
                            }
                            else
                            {
                                args.SocketException = new Exception("Unknown socket error.");
                            }
                        }
                        args.Complete();
                    });
                }
                else
                {
                    args.SocketException = new Exception("Connection state is invalid. Please try reconnecting.");
                    args.Complete();
                }
            }
            catch (ObjectDisposedException)
            {
                // Effectively ignoring this
                args.Complete();
            }
            catch (Exception ex)
            {
                args.SocketException =
                    new Exception("Unable to write to the TCP connection. See inner exception for details.", ex);
                args.Complete();
            }
        }
コード例 #32
0
        public void ConnectAsync(string ipOrHost, int port, SocketEventArgs args)
        {
            CFReadStream  cfRead;
            CFWriteStream cfWrite;

            CFStream.CreatePairWithSocketToHost(ipOrHost, port, out cfRead, out cfWrite);

            // Toll-Free binding from CFStream to a NSStream.
            var inStream  = (NSInputStream)ObjCRuntime.Runtime.GetNSObject(cfRead.Handle);
            var outStream = (NSOutputStream)ObjCRuntime.Runtime.GetNSObject(cfWrite.Handle);
            var pair      = new NSStreamPair(inStream, outStream);

            inStream.Schedule(_socketWorker.RunLoop, NSRunLoop.NSDefaultRunLoopMode);
            outStream.Schedule(_socketWorker.RunLoop, NSRunLoop.NSDefaultRunLoopMode);

            if (args.EncryptionLevel != SocketEncryption.None)
            {
                SetEncryptionOnStreams(args.EncryptionLevel, inStream, outStream);
            }

            var inReady  = false;
            var outReady = false;

            Action complete = () =>
            {
                _socketWorker.ConnectTcpClient(pair, port, args.EncryptionLevel, args.ClientUid);
                args.Complete();
            };

            EventHandler <NSStreamEventArgs> inReadyHandler = null;

            inReadyHandler = (_, e) =>
            {
                inStream.OnEvent -= inReadyHandler;
                inReady           = true;

                if (inReady && outReady)
                {
                    complete();
                }
            };

            EventHandler <NSStreamEventArgs> outReadyHandler = null;

            outReadyHandler = (_, e) =>
            {
                outStream.OnEvent -= outReadyHandler;
                outReady           = true;

                if (inReady && outReady)
                {
                    complete();
                }
            };

            inStream.OnEvent  += inReadyHandler;
            outStream.OnEvent += outReadyHandler;

            inStream.Open();
            outStream.Open();
        }