示例#1
0
        private async Task SendHeadersAsync(WatsonMessage msg, CancellationToken token)
        {
            byte[] headerBytes = msg.HeaderBytes;
            await _DataStream.WriteAsync(headerBytes, 0, headerBytes.Length, token).ConfigureAwait(false);

            await _DataStream.FlushAsync(token).ConfigureAwait(false);
        }
示例#2
0
        internal async Task <WatsonMessage> MessageReadAsync(bool readDataStream)
        {
            WatsonMessage msg = new WatsonMessage(TrafficStream);
            await msg.Build(readDataStream);

            return(msg);
        }
示例#3
0
        /// <summary>
        /// Disconnects the specified client.
        /// </summary>
        /// <param name="ipPort">IP:port of the client.</param>
        public void DisconnectClient(string ipPort)
        {
            if (String.IsNullOrEmpty(ipPort))
            {
                throw new ArgumentNullException(nameof(ipPort));
            }

            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** DisconnectClient unable to find client " + ipPort);
            }
            else
            {
                byte[] data = null;

                if (_ClientsTimedout.ContainsKey(ipPort))
                {
                    data = Encoding.UTF8.GetBytes("Removed from server due to timeout.");
                }
                else
                {
                    data = Encoding.UTF8.GetBytes("Removed from server.");
                    _ClientsKicked.TryAdd(ipPort, DateTime.Now);
                }

                WatsonMessage removeMsg = new WatsonMessage();
                removeMsg.Status        = MessageStatus.Removed;
                removeMsg.Data          = null;
                removeMsg.ContentLength = 0;
                MessageWrite(client, removeMsg, null);

                client.Dispose();
                _Clients.TryRemove(ipPort, out ClientMetadata removed);
            }
        }
示例#4
0
        private async Task <WatsonMessage> MessageReadAsync(ClientMetadata client)
        {
            /*
             *
             * Do not catch exceptions, let them get caught by the data reader
             * to destroy the connection
             *
             */

            WatsonMessage msg = null;

            if (_Mode == Mode.Ssl)
            {
                msg = new WatsonMessage(client.SslStream, Debug);
                await msg.Build();
            }
            else if (_Mode == Mode.Tcp)
            {
                msg = new WatsonMessage(client.NetworkStream, Debug);
                await msg.Build();
            }
            else
            {
                throw new ArgumentException("Unknown mode: " + _Mode.ToString());
            }

            return(msg);
        }
示例#5
0
        private bool MessageWrite(ClientMetadata client, WatsonMessage msg, byte[] data)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }
            if (msg == null)
            {
                throw new ArgumentNullException(nameof(msg));
            }

            int dataLen = 0;

            if (data != null)
            {
                dataLen = data.Length;
            }

            byte[] headerBytes = msg.ToHeaderBytes(dataLen);

            _SendLock.Wait();

            try
            {
                if (_Mode == Mode.Tcp)
                {
                    client.NetworkStream.Write(headerBytes, 0, headerBytes.Length);
                    if (dataLen > 0)
                    {
                        client.NetworkStream.Write(data, 0, dataLen);
                    }
                    client.NetworkStream.Flush();
                }
                else if (_Mode == Mode.Ssl)
                {
                    client.SslStream.Write(headerBytes, 0, headerBytes.Length);
                    if (dataLen > 0)
                    {
                        client.SslStream.Write(data, 0, dataLen);
                    }
                    client.SslStream.Flush();
                }
                else
                {
                    throw new ArgumentException("Unknown mode: " + _Mode.ToString());
                }

                return(true);
            }
            catch (Exception)
            {
                Log("*** MessageWrite " + client.IpPort + " disconnected due to exception");
                return(false);
            }
            finally
            {
                _SendLock.Release();
            }
        }
示例#6
0
        /// <summary>
        /// Tear down the client and dispose of background workers.
        /// </summary>
        public void Dispose()
        {
            Log("Disposing WatsonTcpClient");

            if (Connected)
            {
                WatsonMessage msg = new WatsonMessage();
                msg.Status        = MessageStatus.Disconnecting;
                msg.Data          = null;
                msg.ContentLength = 0;
                MessageWrite(msg);
            }

            if (_TokenSource != null)
            {
                if (!_TokenSource.IsCancellationRequested)
                {
                    _TokenSource.Cancel();
                }
                _TokenSource.Dispose();
                _TokenSource = null;
            }

            if (_WriteLock != null)
            {
                _WriteLock.Dispose();
                _WriteLock = null;
            }

            if (_ReadLock != null)
            {
                _ReadLock.Dispose();
                _ReadLock = null;
            }

            if (_SslStream != null)
            {
                _SslStream.Close();
                _SslStream.Dispose();
                _SslStream = null;
            }

            if (_TcpStream != null)
            {
                _TcpStream.Close();
                _TcpStream.Dispose();
                _TcpStream = null;
            }

            if (_Client != null)
            {
                _Client.Close();
                _Client.Dispose();
                _Client = null;
            }

            Connected = false;
            Log("Dispose routine complete");
        }
示例#7
0
        internal async Task <bool> MessageWriteAsync(WatsonMessage msg, int readStreamBufferSize)
        {
            if (msg == null)
            {
                throw new ArgumentNullException(nameof(msg));
            }

            if (msg.ContentLength > 0)
            {
                if (msg.DataStream == null || !msg.DataStream.CanRead)
                {
                    throw new ArgumentException("Cannot read from supplied stream.");
                }
            }

            byte[] headerBytes = msg.ToHeaderBytes(msg.ContentLength);

            int  bytesRead;
            long bytesRemaining = msg.ContentLength;

            byte[] buffer = new byte[readStreamBufferSize];

            try
            {
                await _WriteLock.WaitAsync();

                await _TrafficStream.WriteAsync(headerBytes, 0, headerBytes.Length);

                if (msg.ContentLength > 0)
                {
                    while (bytesRemaining > 0)
                    {
                        bytesRead = await msg.DataStream.ReadAsync(buffer, 0, buffer.Length);

                        if (bytesRead > 0)
                        {
                            await _TrafficStream.WriteAsync(buffer, 0, bytesRead);

                            bytesRemaining -= bytesRead;
                        }
                    }
                }

                await _TrafficStream.FlushAsync();

                Common.Log($"MessageWriteAsync sent {Encoding.UTF8.GetString(headerBytes)}");
                return(true);
            }
            catch (Exception e)
            {
                Common.Log($"*** MessageWriteAsync {_IpPort} disconnected due to exception: {e.Message}");
                return(false);
            }
            finally
            {
                _WriteLock.Release();
            }
        }
示例#8
0
        /// <summary>
        /// Send data to the specified client, asynchronously.
        /// </summary>
        /// <param name="ipPort">IP:port of the recipient client.</param>
        /// <param name="msg">Populated message object.</param>
        /// <returns>Task with Boolean indicating if the message was sent successfully.</returns>
        public async Task <bool> SendAsync(string ipPort, WatsonMessage msg)
        {
            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** SendAsync unable to find client " + ipPort);
                return(false);
            }

            return(await MessageWriteAsync(client, msg));
        }
示例#9
0
        /// <summary>
        /// Send data to the specified client.
        /// </summary>
        /// <param name="ipPort">IP:port of the recipient client.</param>
        /// <param name="msg">Populated message object.</param>
        /// <returns>Boolean indicating if the message was sent successfully.</returns>
        public bool Send(string ipPort, WatsonMessage msg)
        {
            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** Send unable to find client " + ipPort);
                return(false);
            }

            return(MessageWrite(client, msg));
        }
示例#10
0
        internal bool MessageWrite(WatsonMessage msg, int readStreamBufferSize)
        {
            if (msg == null)
            {
                throw new ArgumentNullException(nameof(msg));
            }

            if (msg.ContentLength > 0)
            {
                if (msg.DataStream == null || !msg.DataStream.CanRead)
                {
                    throw new ArgumentException("Cannot read from supplied stream.");
                }
            }

            byte[] headerBytes = msg.ToHeaderBytes(msg.ContentLength);

            int  bytesRead;
            long bytesRemaining = msg.ContentLength;

            byte[] buffer = new byte[readStreamBufferSize];

            try
            {
                _WriteLock.Wait(1);
                _TrafficStream.Write(headerBytes, 0, headerBytes.Length);

                if (msg.ContentLength > 0)
                {
                    while (bytesRemaining > 0)
                    {
                        bytesRead = msg.DataStream.Read(buffer, 0, buffer.Length);
                        if (bytesRead > 0)
                        {
                            _TrafficStream.Write(buffer, 0, bytesRead);
                            bytesRemaining -= bytesRead;
                        }
                    }
                }

                _TrafficStream.Flush();

                return(true);
            }
            catch (Exception e)
            {
                Common.Log($"*** MessageWrite {_IpPort} disconnected due to exception: {e.Message}");
                return(false);
            }
            finally
            {
                _WriteLock.Release();
            }
        }
示例#11
0
 internal static byte[] ReadMessageDataAsync(WatsonMessage msg, int bufferLen)
 {
     if (msg == null)
     {
         throw new ArgumentNullException(nameof(msg));
     }
     if (msg.ContentLength == 0)
     {
         return(new byte[0]);
     }
     return(WatsonCommon.ReadFromStreamAsync(msg.DataStream, msg.ContentLength, bufferLen));
 }
示例#12
0
        /// <summary>
        /// Send data to the specified client.
        /// </summary>
        /// <param name="ipPort">IP:port of the recipient client.</param>
        /// <param name="data">Byte array containing data.</param>
        /// <returns>Boolean indicating if the message was sent successfully.</returns>
        public bool Send(string ipPort, byte[] data)
        {
            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** Send unable to find client " + ipPort);
                return(false);
            }

            WatsonMessage msg = new WatsonMessage(data, Debug);

            return(MessageWrite(client, msg, data));
        }
示例#13
0
        /// <summary>
        /// Send data to the specified client using a stream, asynchronously.
        /// </summary>
        /// <param name="ipPort">IP:port of the recipient client.</param>
        /// <param name="contentLength">The number of bytes in the stream.</param>
        /// <param name="stream">The stream containing the data.</param>
        /// <returns>Task with Boolean indicating if the message was sent successfully.</returns>
        public async Task <bool> SendAsync(string ipPort, long contentLength, Stream stream)
        {
            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** SendAsync unable to find client " + ipPort);
                return(false);
            }

            WatsonMessage msg = new WatsonMessage(contentLength, stream, Debug);

            return(await MessageWriteAsync(client, msg, contentLength, stream));
        }
示例#14
0
        private async Task <bool> MessageWriteAsync(ClientMetadata client, WatsonMessage msg, byte[] data)
        {
            int          dataLen = 0;
            MemoryStream ms      = new MemoryStream();

            if (data != null && data.Length > 0)
            {
                dataLen = data.Length;
                ms.Write(data, 0, data.Length);
                ms.Seek(0, SeekOrigin.Begin);
            }

            return(await MessageWriteAsync(client, msg, dataLen, ms));
        }
示例#15
0
        internal async Task <bool> MessageWriteAsync(MessageStatus messageStatus, byte[] data, int readStreamBufferSize)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                if (data != null && data.Length > 0)
                {
                    ms.Write(data, 0, data.Length);
                    ms.Seek(0, SeekOrigin.Begin);
                }

                WatsonMessage msg = new WatsonMessage(messageStatus, data.Length, ms);
                return(await MessageWriteAsync(msg, readStreamBufferSize));
            }
        }
示例#16
0
        /// <summary>
        /// Send data and metadata to the server using a stream.
        /// </summary>
        /// <param name="contentLength">The number of bytes in the stream.</param>
        /// <param name="stream">The stream containing the data.</param>
        /// <param name="metadata">Dictionary containing metadata.</param>
        /// <returns>Boolean indicating if the message was sent successfully.</returns>
        public bool Send(long contentLength, Stream stream, Dictionary <object, object> metadata = null)
        {
            if (contentLength < 0)
            {
                throw new ArgumentException("Content length must be zero or greater.");
            }
            if (stream == null)
            {
                stream = new MemoryStream(new byte[0]);
            }
            WatsonMessage msg = new WatsonMessage(metadata, contentLength, stream, false, false, null, null, (_Settings.DebugMessages ? _Settings.Logger : null));

            return(SendInternal(msg, contentLength, stream));
        }
示例#17
0
        /// <summary>
        /// Send data to the specified client, asynchronously.
        /// </summary>
        /// <param name="ipPort">IP:port of the recipient client.</param>
        /// <param name="data">Byte array containing data.</param>
        /// <returns>Task with Boolean indicating if the message was sent successfully.</returns>
        public async Task <bool> SendAsync(string ipPort, byte[] data)
        {
            if (String.IsNullOrEmpty(ipPort))
            {
                throw new ArgumentNullException(nameof(ipPort));
            }
            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** SendAsync unable to find client " + ipPort);
                return(false);
            }

            WatsonMessage msg = new WatsonMessage(data, Debug);

            return(await MessageWriteAsync(client, msg, data));
        }
示例#18
0
        /// <summary>
        /// Send data to the specified client using a stream.
        /// </summary>
        /// <param name="ipPort">IP:port of the recipient client.</param>
        /// <param name="contentLength">The number of bytes in the stream.</param>
        /// <param name="stream">The stream containing the data.</param>
        /// <returns>Boolean indicating if the message was sent successfully.</returns>
        public bool Send(string ipPort, long contentLength, Stream stream)
        {
            if (String.IsNullOrEmpty(ipPort))
            {
                throw new ArgumentNullException(nameof(ipPort));
            }
            if (!_Clients.TryGetValue(ipPort, out ClientMetadata client))
            {
                Log("*** Send unable to find client " + ipPort);
                return(false);
            }

            WatsonMessage msg = new WatsonMessage(contentLength, stream, Debug);

            return(MessageWrite(client, msg, contentLength, stream));
        }
示例#19
0
        private async Task <bool> MessageWriteAsync(ClientMetadata client, WatsonMessage msg)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }
            if (msg == null)
            {
                throw new ArgumentNullException(nameof(msg));
            }

            byte[] msgBytes = msg.ToBytes();

            await _SendLock.WaitAsync();

            try
            {
                if (_Mode == Mode.Tcp)
                {
                    await client.NetworkStream.WriteAsync(msgBytes, 0, msgBytes.Length);

                    await client.NetworkStream.FlushAsync();
                }
                else if (_Mode == Mode.Ssl)
                {
                    await client.SslStream.WriteAsync(msgBytes, 0, msgBytes.Length);

                    await client.SslStream.FlushAsync();
                }
                else
                {
                    throw new ArgumentException("Unknown mode: " + _Mode.ToString());
                }

                return(true);
            }
            catch (Exception)
            {
                Log("*** MessageWriteAsync " + client.IpPort + " disconnected due to exception");
                return(false);
            }
            finally
            {
                _SendLock.Release();
            }
        }
示例#20
0
        /// <summary>
        /// Send a pre-shared key to the server to authenticate.
        /// </summary>
        /// <param name="presharedKey">Up to 16-character string.</param>
        public void Authenticate(string presharedKey)
        {
            if (String.IsNullOrEmpty(presharedKey))
            {
                throw new ArgumentNullException(nameof(presharedKey));
            }
            if (presharedKey.Length != 16)
            {
                throw new ArgumentException("Preshared key length must be 16 bytes.");
            }

            WatsonMessage msg = new WatsonMessage();

            msg.Status       = MessageStatus.AuthRequested;
            msg.PresharedKey = Encoding.UTF8.GetBytes(presharedKey);
            SendInternal(msg, 0, null);
        }
示例#21
0
        private void FinalizeConnection(ClientMetadata client)
        {
            #region Add-to-Client-List

            if (!AddClient(client))
            {
                Log("*** FinalizeConnection unable to add client " + client.IpPort);
                client.Dispose();
                return;
            }

            // Do not decrement in this block, decrement is done by the connection reader
            int activeCount = Interlocked.Increment(ref _ActiveClients);

            #endregion

            #region Request-Authentication

            if (!String.IsNullOrEmpty(PresharedKey))
            {
                Log("*** FinalizeConnection soliciting authentication material from " + client.IpPort);
                _UnauthenticatedClients.TryAdd(client.IpPort, DateTime.Now);

                byte[]        data    = Encoding.UTF8.GetBytes("Authentication required");
                WatsonMessage authMsg = new WatsonMessage();
                authMsg.Status        = MessageStatus.AuthRequired;
                authMsg.Data          = null;
                authMsg.ContentLength = 0;
                MessageWrite(client, authMsg, null);
            }

            #endregion

            #region Start-Data-Receiver

            Log("*** FinalizeConnection starting data receiver for " + client.IpPort + " (now " + activeCount + " clients)");
            if (ClientConnected != null)
            {
                Task.Run(() => ClientConnected(client.IpPort));
            }

            Task.Run(async() => await DataReceiver(client));

            #endregion
        }
示例#22
0
        /// <summary>
        /// Disconnect from the server.
        /// </summary>
        public void Disconnect()
        {
            if (!Connected)
            {
                throw new InvalidOperationException("Nonnected to the server.");
            }

            _Settings.Logger?.Invoke(_Header + "disconnecting");

            if (Connected)
            {
                WatsonMessage msg = new WatsonMessage();
                msg.Status = MessageStatus.Shutdown;
                SendInternal(msg, 0, null);
            }

            if (_TokenSource != null)
            {
                // stop the data receiver
                if (!_TokenSource.IsCancellationRequested)
                {
                    _TokenSource.Cancel();
                    _TokenSource.Dispose();
                }
            }

            if (_SslStream != null)
            {
                _SslStream.Close();
            }

            if (_TcpStream != null)
            {
                _TcpStream.Close();
            }

            if (_Client != null)
            {
                _Client.Close();
            }

            Connected = false;

            _Settings.Logger?.Invoke(_Header + "disconnected");
        }
示例#23
0
        private bool MessageWrite(ClientMetadata client, WatsonMessage msg, byte[] data)
        {
            int          dataLen = 0;
            MemoryStream ms      = new MemoryStream();

            if (data != null && data.Length > 0)
            {
                dataLen = data.Length;
                ms.Write(data, 0, data.Length);
                ms.Seek(0, SeekOrigin.Begin);
            }
            else
            {
                ms = new MemoryStream(new byte[0]);
            }

            return(MessageWrite(client, msg, dataLen, ms));
        }
示例#24
0
        /// <summary>
        /// Send a pre-shared key to the server to authenticate.
        /// </summary>
        /// <param name="presharedKey">Up to 16-character string.</param>
        public void Authenticate(string presharedKey)
        {
            if (String.IsNullOrEmpty(presharedKey))
            {
                throw new ArgumentNullException(nameof(presharedKey));
            }
            if (presharedKey.Length > 16)
            {
                throw new ArgumentException("Preshared key length must be 16 or fewer characters");
            }

            presharedKey = presharedKey.PadRight(16, ' ');
            WatsonMessage msg = new WatsonMessage(Encoding.UTF8.GetBytes(presharedKey), Debug);

            msg.Status       = MessageStatus.AuthRequired;
            msg.PresharedKey = Encoding.UTF8.GetBytes(presharedKey);
            Send(msg);
        }
示例#25
0
        /// <summary>
        /// Send data and metadata to the server from a stream asynchronously.
        /// </summary>
        /// <param name="contentLength">The number of bytes to send.</param>
        /// <param name="stream">The stream containing the data.</param>
        /// <param name="metadata">Dictionary containing metadata.</param>
        /// <param name="token">Cancellation token to cancel the request.</param>
        /// <returns>Task with Boolean indicating if the message was sent successfully.</returns>
        public async Task <bool> SendAsync(long contentLength, Stream stream, Dictionary <object, object> metadata = null, CancellationToken token = default)
        {
            if (contentLength < 0)
            {
                throw new ArgumentException("Content length must be zero or greater.");
            }
            if (token == default(CancellationToken))
            {
                token = _Token;
            }
            if (stream == null)
            {
                stream = new MemoryStream(new byte[0]);
            }
            WatsonMessage msg = new WatsonMessage(metadata, contentLength, stream, false, false, null, null, (_Settings.DebugMessages ? _Settings.Logger : null));

            return(await SendInternalAsync(msg, contentLength, stream, token).ConfigureAwait(false));
        }
示例#26
0
        private void FinalizeConnection(ClientMetadata client)
        {
            #region Add-to-Client-List

            ClientMetadata removed = null;
            DateTime       ts;

            _Clients.TryRemove(client.IpPort, out removed);
            _ClientsLastSeen.TryRemove(client.IpPort, out ts);

            _Clients.TryAdd(client.IpPort, client);
            _ClientsLastSeen.TryAdd(client.IpPort, DateTime.Now);

            #endregion Add-to-Client-List

            #region Request-Authentication

            if (!String.IsNullOrEmpty(PresharedKey))
            {
                Log("*** FinalizeConnection soliciting authentication material from " + client.IpPort);
                _UnauthenticatedClients.TryAdd(client.IpPort, DateTime.Now);

                byte[]        data    = Encoding.UTF8.GetBytes("Authentication required");
                WatsonMessage authMsg = new WatsonMessage();
                authMsg.Status        = MessageStatus.AuthRequired;
                authMsg.Data          = null;
                authMsg.ContentLength = 0;
                MessageWrite(client, authMsg, null);
            }

            #endregion Request-Authentication

            #region Start-Data-Receiver

            Log("*** FinalizeConnection starting data receiver for " + client.IpPort);
            if (ClientConnected != null)
            {
                Task.Run(() => ClientConnected(client.IpPort));
            }

            Task.Run(async() => await DataReceiver(client, client.Token));

            #endregion Start-Data-Receiver
        }
示例#27
0
        /// <summary>
        /// Send data and wait for a response for the specified number of milliseconds.  A TimeoutException will be thrown if a response is not received.
        /// </summary>
        /// <param name="timeoutMs">Number of milliseconds to wait before considering a request to be expired.</param>
        /// <param name="contentLength">The number of bytes to send from the supplied stream.</param>
        /// <param name="stream">Stream containing data.</param>
        /// <param name="metadata">Metadata dictionary to attach to the message.</param>
        /// <returns>SyncResponse.</returns>
        public SyncResponse SendAndWait(int timeoutMs, long contentLength, Stream stream, Dictionary <object, object> metadata = null)
        {
            if (contentLength < 0)
            {
                throw new ArgumentException("Content length must be zero or greater.");
            }
            if (timeoutMs < 1000)
            {
                throw new ArgumentException("Timeout milliseconds must be 1000 or greater.");
            }
            if (stream == null)
            {
                stream = new MemoryStream(new byte[0]);
            }
            DateTime      expiration = DateTime.Now.AddMilliseconds(timeoutMs);
            WatsonMessage msg        = new WatsonMessage(metadata, contentLength, stream, true, false, expiration, Guid.NewGuid().ToString(), (_Settings.DebugMessages ? _Settings.Logger : null));

            return(SendAndWaitInternal(msg, timeoutMs, contentLength, stream));
        }
示例#28
0
        /// <summary>
        /// Send a pre-shared key to the server to authenticate.
        /// </summary>
        /// <param name="presharedKey">Up to 16-character string.</param>
        public void Authenticate(string presharedKey)
        {
            if (String.IsNullOrEmpty(presharedKey))
            {
                throw new ArgumentNullException(nameof(presharedKey));
            }
            if (presharedKey.Length != 16)
            {
                throw new ArgumentException("Preshared key length must be 16 bytes.");
            }

            presharedKey = presharedKey.PadRight(16, ' ');
            WatsonMessage msg = new WatsonMessage();

            msg.Status        = MessageStatus.AuthRequested;
            msg.PresharedKey  = Encoding.UTF8.GetBytes(presharedKey);
            msg.Data          = null;
            msg.ContentLength = 0;
            MessageWrite(msg);
        }
示例#29
0
        internal static DateTime GetExpirationTimestamp(WatsonMessage msg)
        {
            DateTime expiration = msg.Expiration.Value;

            if (msg.SenderTimestamp != null)
            {
                //
                // TimeSpan will be negative if sender timestamp is earlier than now or positive if sender timestamp is later than now
                // Goal #1: if sender has a later timestamp, decrease expiration by the difference between sender time and our time
                // Goal #2: if sender has an earlier timestamp, increase expiration by the difference between sender time and our time
                //
                // E.g. If sender time is 10:40 and receiver time is 10:45 and expiration is 1 minute, so 10:41.
                // ts = 10:45 - 10:40 = 5 minutes
                // expiration = 10:41 + 5 = 10:46 which is 1 minute later than when receiver received the message
                //
                TimeSpan ts = DateTime.Now - msg.SenderTimestamp.Value;
                expiration = expiration.AddMilliseconds(ts.TotalMilliseconds);
            }

            return(expiration);
        }
示例#30
0
        internal static async Task <byte[]> ReadMessageDataAsync(WatsonMessage msg, int bufferLen)
        {
            if (msg == null)
            {
                throw new ArgumentNullException(nameof(msg));
            }
            if (msg.ContentLength == 0)
            {
                return(new byte[0]);
            }

            byte[]       msgData = null;
            MemoryStream ms      = new MemoryStream();

            if (msg.Compression == CompressionType.None)
            {
                msgData = await WatsonCommon.ReadFromStreamAsync(msg.DataStream, msg.ContentLength, bufferLen);
            }
            else if (msg.Compression == CompressionType.Deflate)
            {
                using (DeflateStream ds = new DeflateStream(msg.DataStream, CompressionMode.Decompress, true))
                {
                    msgData = WatsonCommon.ReadStreamFully(ds);
                }
            }
            else if (msg.Compression == CompressionType.Gzip)
            {
                using (GZipStream gs = new GZipStream(msg.DataStream, CompressionMode.Decompress, true))
                {
                    msgData = WatsonCommon.ReadStreamFully(gs);
                }
            }
            else
            {
                throw new InvalidOperationException("Unknown compression type: " + msg.Compression.ToString());
            }

            return(msgData);
        }