Ejemplo n.º 1
0
        /// <summary>
        /// This method is invoked when an asynchronous receive operation completes.
        /// If the remote host closed the connection, then the socket is closed.
        /// If data was received then the data is echoed back to the client.
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed receive operation.</param>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            try
            {
                log.DebugFormat("{0}/ProcessReceive received started...", _fileNm);

                // Check if the remote host closed the connection.
                if (e.BytesTransferred > 0)
                {
                    if (e.SocketError == SocketError.Success)
                    {
                        StateObject state = e.UserToken as StateObject;
                        if (state == null)// Already closed
                        {
                            return;
                        }
                        #region Process Protocol

                        string     DeviceId = state.DeviceId;
                        DeviceInfo di       = DeviceData.GetDeviceById(DeviceId);

                        di.TrackerDataActionTime = DateTime.UtcNow;
                        try
                        {
                            di.TrackerIp = state.Connection.RemoteEndPoint.ToString();
                        }
                        catch (Exception ex)
                        { }

                        //TODO memory will increase in this case
                        di.RawData = new byte[e.BytesTransferred];
                        di.RawData = e.Buffer.Take(e.BytesTransferred).ToArray();

                        log.DebugFormat("{0}/ProcessReceive received for Parse data: {1}", _fileNm, BitConverter.ToString(di.RawData));
                        di = Protocol.Parser.Process(state.ProtocolParser, di);
                        log.DebugFormat("{0}/ProcessReceive to send to client: {1}", _fileNm, di.ToSendRawData);

                        if (di.Payload != null && di.Payload.Length > 0 &&
                            di.ParserStatus == ProtocolParserStatus.Initialized)
                        {
                            // Unparsed junk stored in Payload,
                            // Close the connection to avoid payload increase in its size
                            this.CloseClientSocket(e);
                            return;
                        }

                        if (string.IsNullOrWhiteSpace(DeviceId))
                        {
                            //Close existing connection
                            DeviceData.GetExistingConnectionsByDeviceId(di.DeviceId).ForEach(eCon =>
                            {
                                Console.WriteLine("Closing >>>>>>>>>>>>>>> {0}", di.DeviceId);
                                CloseClientSocket(eCon);
                            });

                            //DeviceData.RemoveConnectionsByDeviceId(di.DeviceId); handled in CloseClientSocket

                            // Add new connection
                            DeviceData.AddConnection(di.DeviceId, e);
                        }

                        state.DeviceId = di.DeviceId;
                        DeviceData.UpdateDevice(di);

                        if (di.ToSendRawData != null && di.ToSendRawData.Length > 0)
                        {
                            //if (state.Connection.Available == 0)
                            {
                                // TODO sent to device
                                log.DebugFormat("{0}/ProcessReceive {1}", _fileNm,
                                                BitConverter.ToString(di.ToSendRawData));
                                e.SetBuffer(di.ToSendRawData, 0, di.ToSendRawData.Length);
                                try
                                {
                                    // Set return buffer.
                                    if (!state.Connection.SendAsync(e))
                                    {
                                        // Set the buffer to send back to the client.
                                        this.ProcessSend(e);
                                    }
                                }
                                catch (Exception)
                                {
                                }
                            }
                            di.ToSendRawData = new byte[0];
                        }
                        else
                        {
                            log.DebugFormat("{0}/ProcessReceive received Bind receive for next data...", _fileNm);
                            try
                            {
                                if (!state.Connection.ReceiveAsync(e))
                                {
                                    // Read the next block of data sent by client.
                                    this.ProcessReceive(e);
                                }
                            }
                            catch (Exception ex)
                            {
                            }
                        }

                        #endregion
                    }
                    else
                    {
                        this.ProcessError(e);
                    }
                }
                else
                {
                    log.DebugFormat("ProcessAccept: >>>> Try 3 for connection close state");
                    // Closed by client
                    this.CloseClientSocket(e);
                }
            }
            catch (Exception)
            {
            }
        }