Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="client">The client that sent messages.</param>
        /// <param name="type">The message type</param>
        /// <param name="payload"></param>
        private void SendOnReceived(Socket client, SQLiteMessage type, byte[] payload)
        {
            // are we a 'send and wait type'?
            // if we are then send... and wait for a response.
            // if no respinse is sent... send one.
            if (type == SQLiteMessage.SendAndWaitRequest)
            {
                var packet = new PacketResponse(payload);
                OnReceived(
                    packet.Packet,
                    (p) =>
                {
                    // send whatever response the client wants us to.
                    // but we need to send it back as a response.
                    var response = new PacketResponse(SQLiteMessage.SendAndWaitResponse, p.Packed, packet.Guid);
                    SendToClient(client, response.Packed);
                }
                    );
                return;
            }

            OnReceived(
                new Packet(type, payload),
                (p) => {
                // send whatever response the client wants us to.
                SendToClient(client, p.Packed);
            }
                );
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get a value from the server by index.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="requestType"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private async Task <T> GetIndexedValueAsync <T>(SQLiteMessage requestType, int index)
        {
            ThrowIfNoCommand();
            var getValue = new GuidAndIndexRequest()
            {
                Guid  = _parentCommand.Guid,
                Index = index
            };
            var fields = Fields.Fields.SerializeObject(getValue);

            var response = await _controller.SendAndWaitAsync(requestType, fields.Pack(), _queryTimeouts).ConfigureAwait(false);

            switch (response.Message)
            {
            case SQLiteMessage.SendAndWaitTimeOut:
                throw new TimeoutException("There was a timeout error executing the read request from the reader.");

            case SQLiteMessage.ExecuteRequestResponse:
                return(response.Get <T>());

            case SQLiteMessage.ExecuteReaderException:
                var error = response.Get <string>();
                throw new SQLiteServerException(error);

            default:
                throw new InvalidOperationException($"Unknown response {response.Message} from the server.");
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get the result of a requres.t
        /// </summary>
        /// <param name="requestType"></param>
        /// <returns></returns>
        private async Task <T> GetGuiOnlyValueAsync <T>(SQLiteMessage requestType)
        {
            ThrowIfNoCommand();
            var response = await _controller.SendAndWaitAsync(requestType, Encoding.ASCII.GetBytes(_parentCommand.Guid), _queryTimeouts).ConfigureAwait(false);

            switch (response.Message)
            {
            case SQLiteMessage.SendAndWaitTimeOut:
                throw new TimeoutException("There was a timeout error executing the read request from the reader.");

            case SQLiteMessage.ExecuteReaderReadResponse:
            case SQLiteMessage.ExecuteReaderGetRowResponse:
                var fields = Fields.Fields.Unpack(response.Payload);
                return(Fields.Fields.DeserializeObject <T>(fields));

            case SQLiteMessage.ExecuteRequestResponse:
                return(response.Get <T>());

            case SQLiteMessage.ExecuteReaderException:
                var error = response.Get <string>();
                throw new SQLiteServerException(error);

            default:
                throw new InvalidOperationException($"Unknown response {response.Message} from the server.");
            }
        }
Ejemplo n.º 4
0
        public async Task <Packet> SendAndWaitAsync(SQLiteMessage type, byte[] data, int timeout)
        {
            // create the packer
            var packer = new ResponsePacketHandler(this, WaitForResponseSleepTime);

            // send and wait for the response.
            return(await packer.SendAndWaitAsync(type, data, timeout).ConfigureAwait(false));
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Send a message to the clients or to the master.
 /// @todo we need to fix this function as it is not a good use case.
 /// </summary>
 /// <param name="type"></param>
 /// <param name="data"></param>
 public void Send(SQLiteMessage type, byte[] data)
 {
     if (Server)
     {
         SendToClients(type, data);
     }
     else
     {
         SendToServer(type, data);
     }
 }
Ejemplo n.º 6
0
        private long GetBusyTimeoutInMs(SQLiteMessage packetMessage)
        {
            switch (packetMessage)
            {
            case SQLiteMessage.CreateCommandException:
            case SQLiteMessage.ExecuteNonQueryRequest:
            case SQLiteMessage.ExecuteCommandNonQueryRequest:
            case SQLiteMessage.ExecuteCommandReaderRequest:
            case SQLiteMessage.ExecuteReaderRequest:
                return(CommandTimeout == 0 ? DefaultBusyTimeout : Convert.ToInt64((CommandTimeout * 1000) * 0.10));

            default:
                return(DefaultBusyTimeout);
            }
        }
Ejemplo n.º 7
0
        public PacketResponse(SQLiteMessage type, byte[] payload, string guid)
        {
            // make sure that the guid is the len we want it to be
            // anything other than that and we have issues.
            if (guid == null)
            {
                throw new ArgumentNullException(nameof(guid), "The given Guid cannot be null.");
            }
            if (guid.Length != GuidLen)
            {
                throw new Exception($"The length of our guid ({guid}), has changed from the expected len({GuidLen}.");
            }
            Guid = guid;

            Type    = type;
            Payload = payload;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Repack the type/data/guid so we can send it all in one go.
        /// </summary>
        private static byte[] Pack(SQLiteMessage type, byte[] payload, string guid)
        {
            // get the final size.
            // [int] payload len
            // [uint] type
            // [37] guid payload.
            var totalSize = sizeof(uint) + sizeof(int) + (payload?.Length ?? 0) + GuidLen;
            var bytes     = new byte[totalSize];

            var bLen  = BitConverter.GetBytes((payload?.Length ?? 0) + GuidLen);
            var bType = BitConverter.GetBytes((uint)type);
            var bGuid = Encoding.ASCII.GetBytes(guid);

            // add the len
            var dstOffset = 0;

            Buffer.BlockCopy(bLen, 0, bytes, dstOffset, sizeof(int));
            dstOffset += sizeof(int);

            Buffer.BlockCopy(bType, 0, bytes, dstOffset, sizeof(uint));
            dstOffset += sizeof(uint);

            if (payload != null && payload.Length > 0)
            {
                Buffer.BlockCopy(payload, 0, bytes, dstOffset, payload.Length);
                dstOffset += payload.Length;
            }

            // finally the guid
            Buffer.BlockCopy(bGuid, 0, bytes, dstOffset, bGuid.Length);
            dstOffset += bGuid.Length;

            // sanity check
            if (dstOffset != totalSize)
            {
                throw new Exception("There was an issue re-creating the response packet.");
            }

            // we can now return the payload.
            return(bytes);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Send a request to the server and wait for a response.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="data"></param>
        /// <param name="timeout">The max number of ms we will be waitng.</param>
        /// <returns>The response packet</returns>
        public async Task <Packet> SendAndWaitAsync(SQLiteMessage type, byte[] data, int timeout)
        {
            // listen for new messages.
            Packet response = null;
            var    watch    = System.Diagnostics.Stopwatch.StartNew();

            var received = new ConnectionsController.DelegateOnReceived((p, r) =>
            {
                lock (_lock)
                {
                    try
                    {
                        // is it the response we might be waiting for?
                        if (p.Message != SQLiteMessage.SendAndWaitResponse)
                        {
                            // it is not a response, so we are not really interested.
                            return;
                        }

                        // it looks like a posible match
                        // so we will try and unpack it and see if it is the actual response.
                        var packetResponse = new PacketResponse(p.Packed);
                        if (packetResponse.Guid != _guid)
                        {
                            // not the response packet we were looking for.
                            return;
                        }

                        // we cannot use the payload of packet.Payload as it is
                        // it is the payload of "Types.SendAndWaitResponse"
                        var r2 = new Packet(packetResponse.Payload);
                        if (r2.Message == SQLiteMessage.SendAndWaitBusy)
                        {
                            watch.Restart();
                            return;
                        }
                        response = r2;
                    }
                    catch
                    {
                        response = null;
                    }
                }
            });

            // start listenting
            _connection.OnReceived += received;

            // try and send.
            try
            {
                // the packet handler.
                var packet = new PacketResponse(type, data);

                // save the guid we are looking for.
                _guid = packet.Guid;

                // send the data and wait for a response.
                _connection.Send(SQLiteMessage.SendAndWaitRequest, packet.Packed);

                await Task.Run(async() => {
                    watch.Restart();
                    while (response == null)
                    {
                        // delay a little to give other thread a chance.
                        if (_waitForResponseSleepTime > 0)
                        {
                            await Task.Delay(_waitForResponseSleepTime).ConfigureAwait(false);
                        }
                        else
                        {
                            await Task.Yield();
                        }

                        // check for delay
                        if (timeout > 0 && watch.ElapsedMilliseconds >= timeout * 1000)
                        {
                            // we timed out.
                            break;
                        }
                    }
                    watch.Stop();
                }).ConfigureAwait(false);
            }
            finally
            {
                // whatever happens, we are no longer listening
                _connection.OnReceived -= received;
            }

            // return what we found.
            return(response ?? new Packet(SQLiteMessage.SendAndWaitTimeOut, 1));
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Send a single message to the master.
 /// </summary>
 /// <param name="type"></param>
 /// <param name="data"></param>
 private void SendToServer(SQLiteMessage type, byte[] data)
 {
     SendToServer(new Packet(type, data));
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Send a message to all the listening clients.
 /// </summary>
 /// <param name="type"></param>
 /// <param name="data"></param>
 private void SendToClients(SQLiteMessage type, byte[] data)
 {
     SendToClients(new Packet(type, data));
 }
Ejemplo n.º 12
0
 public PacketResponse(SQLiteMessage type, byte[] payload) :
     this(type, payload, System.Guid.NewGuid().ToString())
 {
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Constructor with a string
 /// </summary>
 /// <param name="message"></param>
 /// <param name="payload"></param>
 public Packet(SQLiteMessage message, string payload)
 {
     Payload = payload == null ? null : Encoding.ASCII.GetBytes(payload);
     Message = message;
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Constructor with a byte array
 /// </summary>
 /// <param name="message"></param>
 /// <param name="payload"></param>
 public Packet(SQLiteMessage message, byte[] payload)
 {
     Payload = payload;
     Message = message;
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Constructor with an int.
 /// </summary>
 /// <param name="message"></param>
 /// <param name="payload"></param>
 public Packet(SQLiteMessage message, long payload)
 {
     Payload = BitConverter.GetBytes(payload);
     Message = message;
 }