/// <summary> /// Initializes a new instance of the <see cref="OutputRequest"/> class. /// </summary> /// <param name="messageOjectStream"> The message object stream to use for sending the requests.</param> /// <param name="messageDispatcher">The message dispatcher to use for message interception.</param> public OutputRequest(XmlObjectStream messageOjectStream, MessageDispatcher messageDispatcher) { if (messageOjectStream == null) { throw new ArgumentException("Invalid messageOjectStream specified."); } if (messageDispatcher == null) { throw new ArgumentException("Invalid messageDispatcher specified."); } _messageOjectStream = messageOjectStream; _messageDispatcher = messageDispatcher; this.Details = new Details(); }
/// <summary> /// Stops the message reading and dispatching on the current message object stream. /// </summary> public void Stop() { lock (_syncLock) { if (_messageReaderThread == null) { return; } _messageObjectStream.Cancel(); _threadDownEvent.WaitOne(); _messageObjectStream = null; _messageReaderThread = null; } }
/// <summary> /// Starts the message reading and dispatching on the specified message object stream. /// </summary> /// <param name="messageObjectStream">Message object stream to read the messages from.</param> public void Start(XmlObjectStream messageObjectStream) { if (messageObjectStream == null) { throw new ArgumentException("Invalid messageObjectStream specified."); } Stop(); lock (_syncLock) { _threadDownEvent.Reset(); _messageObjectStream = messageObjectStream; _messageReaderThread = new Thread(new ThreadStart(MessageReader)); _messageReaderThread.Start(); } }
/// <summary> /// Initializes a new instance of the <see cref="InitiateInputRequest" /> class. /// </summary> /// <param name="messageOjectStream">The message object stream to use for sending the requests.</param> /// <param name="messageDispatcher">The message dispatcher to use for message interception.</param> /// <param name="deliveryNumber">The delivery number to use for the initiated input.</param> public InitiateInputRequest(XmlObjectStream messageOjectStream, MessageDispatcher messageDispatcher, string deliveryNumber) { if (messageOjectStream == null) { throw new ArgumentException("Invalid messageOjectStream specified."); } if (messageDispatcher == null) { throw new ArgumentException("Invalid messageDispatcher specified."); } _messageOjectStream = messageOjectStream; _messageDispatcher = messageDispatcher; _deliveryNumber = deliveryNumber; this.IsNewDelivery = (deliveryNumber != null).ToString(); this.Details = new Details(); }
/// <summary> /// Stops the message reading and dispatching on the current message object stream. /// </summary> public void Stop() { lock (_syncLock) { if (_messageReaderThread == null) { return; } this.Trace("Stopping the message reading and dispatching on the current message object stream."); _messageObjectStream.Cancel(); _threadDownEvent.WaitOne(); _messageObjectStream = null; _messageReaderThread = null; this.Trace("The message reading and dispatching on the current message object stream are stopped."); } }
/// <summary> /// Performs a graceful shutdown of the digital shelf connection. /// </summary> public void Disconnect() { lock (_syncLock) { if (_messageObjectStream == null) { return; } this.Trace("Closing connection to digital shelf."); base.ResetEventQueue(); if ((_shutdownThreadEvent != null) && (_shutdownThreadEvent.SafeWaitHandle.IsClosed == false)) { _shutdownThreadEvent.Set(); } _shutdownThreadEvent = null; _messageDispatcher.Stop(); _messageObjectStream.Dispose(); _messageObjectStream = null; if (_client.Connected) { try { _client.Client.Shutdown(SocketShutdown.Both); } catch (Exception ex) { this.Error("Shutdown of the connected TCP client failed!", ex); } } _client.Close(); _client = null; } }
/// <summary> /// Establishes a new connection to the digital shelf with the the specified host at the specified port. /// This method performs an implicit disconnect if there is already an active digital shelf connection. /// </summary> /// <param name="host">The name or ip address of the digital shelf.</param> /// <param name="port">The port number of the digital shelf. Default is 6050.</param> public void Connect(string host, ushort port = 6052) { if (string.IsNullOrEmpty(host)) { throw new ArgumentException("Invalid host specified."); } if (port == 0) { throw new ArgumentException("Invalid port specified."); } Disconnect(); lock (_syncLock) { this.Trace("Connecting to digital shelf '{0}' at port '{1}'.", host, port); _client = new TcpClient(); var connectResult = _client.BeginConnect(host, (int)port, null, null); if (connectResult.AsyncWaitHandle.WaitOne(ConnectTimeout) == false) { connectResult.AsyncWaitHandle.Close(); _client.Close(); _client = null; this.Error("Connecting to digital shelf '{0}' at port '{1}' timed out.", host, port); throw new TimeoutException(string.Format("Connecting to digital shelf '{0}' at port '{1}' timed out.", host, port)); } _client.EndConnect(connectResult); _client.ReceiveTimeout = 0; _client.IncreaseReadBufferSize(); _client.EnableSocketKeepAlive(); // initialize message stream and register the supported XML message types _messageObjectStream = new XmlObjectStream(_client.GetStream(), "WWKS", "DigitalShelf", string.Concat(host, ":", port)); _messageObjectStream.AddSupportedType(typeof(HelloRequestEnvelope), typeof(HelloRequest).Name); _messageObjectStream.AddSupportedType(typeof(HelloResponseEnvelope), typeof(HelloResponse).Name); _messageObjectStream.AddSupportedType(typeof(ArticleInfoRequestEnvelope), typeof(ArticleInfoRequest).Name); _messageObjectStream.AddSupportedType(typeof(ArticleInfoResponseEnvelope), typeof(ArticleInfoResponse).Name); _messageObjectStream.AddSupportedType(typeof(ArticlePriceRequestEnvelope), typeof(ArticlePriceRequest).Name); _messageObjectStream.AddSupportedType(typeof(ArticlePriceResponseEnvelope), typeof(ArticlePriceResponse).Name); _messageObjectStream.AddSupportedType(typeof(ArticleSelectedMessageEnvelope), typeof(ArticleSelectedMessage).Name); _messageObjectStream.AddSupportedType(typeof(ShoppingCartRequestEnvelope), typeof(ShoppingCartRequest).Name); _messageObjectStream.AddSupportedType(typeof(ShoppingCartResponseEnvelope), typeof(ShoppingCartResponse).Name); _messageObjectStream.AddSupportedType(typeof(ShoppingCartUpdateRequestEnvelope), typeof(ShoppingCartUpdateRequest).Name); _messageObjectStream.AddSupportedType(typeof(ShoppingCartUpdateResponseEnvelope), typeof(ShoppingCartUpdateResponse).Name); _messageObjectStream.AddSupportedType(typeof(ShoppingCartUpdateMessageEnvelope), typeof(ShoppingCartUpdateMessage).Name); _messageObjectStream.AddSupportedType(typeof(StockInfoRequestEnvelope), typeof(StockInfoRequest).Name); _messageObjectStream.AddSupportedType(typeof(StockInfoResponseEnvelope), typeof(StockInfoResponse).Name); if (ProcessHandshake() == false) { Disconnect(); throw new ApplicationException("Processing WWKS protocol handshake failed."); } _messageDispatcher.Start(_messageObjectStream); _shutdownThreadEvent = new ManualResetEvent(false); // TODO: Implement ConnectionCheck. //if (ThreadPool.QueueUserWorkItem(new WaitCallback(ConnectionCheck), _shutdownThreadEvent) == false) //{ // Disconnect(); // throw new ApplicationException("Starting background connection check thread failed."); //} } }
/// <summary> /// Initializes a new instance of the <see cref="WwksConverterStream"/> class. /// </summary> /// <param name="converterID">The identifier of the according converter.</param> /// <param name="connection">The underlying connection to use.</param> /// <param name="configuration">The converter configuration to use.</param> public WwksConverterStream(int converterID, IConnection connection, WwksConverterConfiguration configuration) { if (connection == null) { throw new ArgumentException("Invalid connection specified."); } if (configuration == null) { throw new ArgumentException("Invalid configuration specified."); } _converterID = converterID; _connection = connection; _configuration = configuration; _objectStream = new XmlObjectStream(_connection.ConnectionStream, "WWKS", _configuration.EnableMessageTrace ? connection.Category.ToString() : null, _configuration.EnableMessageTrace ? connection.EndPoint : null); // add WWKS message set _objectStream.AddSupportedType(typeof(KeepAliveRequestEnvelope), typeof(KeepAliveRequest).Name); _objectStream.AddSupportedType(typeof(KeepAliveResponseEnvelope), typeof(KeepAliveResponse).Name); _objectStream.AddSupportedType(typeof(HelloRequestEnvelope), typeof(HelloRequest).Name); _objectStream.AddSupportedType(typeof(HelloResponseEnvelope), typeof(HelloResponse).Name); _objectStream.AddSupportedType(typeof(InputMessageEnvelope), typeof(InputMessage).Name); _objectStream.AddSupportedType(typeof(InputRequestEnvelope), typeof(InputRequest).Name); _objectStream.AddSupportedType(typeof(InputResponseEnvelope), typeof(InputResponse).Name); _objectStream.AddSupportedType(typeof(StatusRequestEnvelope), typeof(StatusRequest).Name); _objectStream.AddSupportedType(typeof(StatusResponseEnvelope), typeof(StatusResponse).Name); _objectStream.AddSupportedType(typeof(StockInfoRequestEnvelope), typeof(StockInfoRequest).Name); _objectStream.AddSupportedType(typeof(TaskCancelRequestEnvelope), typeof(TaskCancelRequest).Name); _objectStream.AddSupportedType(typeof(TaskCancelResponseEnvelope), typeof(TaskCancelResponse).Name); _objectStream.AddSupportedType(typeof(TaskInfoRequestEnvelope), typeof(TaskInfoRequest).Name); _objectStream.AddSupportedType(typeof(TaskInfoResponseEnvelope), typeof(TaskInfoResponse).Name); _objectStream.AddSupportedType(typeof(ArticleMasterSetResponseEnvelope), typeof(ArticleMasterSetResponse).Name); _objectStream.AddSupportedType(typeof(StockDeliverySetResponseEnvelope), typeof(StockDeliverySetResponse).Name); _objectStream.AddSupportedType(typeof(UnprocessedMessageEnvelope), typeof(UnprocessedMessage).Name); if (_configuration.SmallMessageSet) { _objectStream.AddSupportedType(typeof(OutputRequestSmallSetEnvelope), typeof(OutputRequest).Name); _objectStream.AddSupportedType(typeof(OutputResponseSmallSetEnvelope), typeof(OutputResponse).Name); _objectStream.AddSupportedType(typeof(OutputMessageSmallSetEnvelope), typeof(OutputMessage).Name); _objectStream.AddSupportedType(typeof(StockInfoResponseSmallSetEnvelope), typeof(StockInfoResponse).Name); _objectStream.AddSupportedType(typeof(StockInfoMessageSmallSetEnvelope), typeof(StockInfoMessage).Name); _objectStream.AddSupportedType(typeof(ArticleMasterSetRequestSmallSetEnvelope), typeof(ArticleMasterSetRequest).Name); _objectStream.AddSupportedType(typeof(StockDeliverySetRequestSmallSetEnvelope), typeof(StockDeliverySetRequest).Name); } else { _objectStream.AddSupportedType(typeof(OutputRequestEnvelope), typeof(OutputRequest).Name); _objectStream.AddSupportedType(typeof(OutputResponseEnvelope), typeof(OutputResponse).Name); _objectStream.AddSupportedType(typeof(OutputMessageEnvelope), typeof(OutputMessage).Name); _objectStream.AddSupportedType(typeof(StockInfoResponseEnvelope), typeof(StockInfoResponse).Name); _objectStream.AddSupportedType(typeof(StockInfoMessageEnvelope), typeof(StockInfoMessage).Name); _objectStream.AddSupportedType(typeof(ArticleMasterSetRequestEnvelope), typeof(ArticleMasterSetRequest).Name); _objectStream.AddSupportedType(typeof(StockDeliverySetRequestEnvelope), typeof(StockDeliverySetRequest).Name); _objectStream.AddSupportedType(typeof(InitiateInputMessageEnvelope), typeof(InitiateInputMessage).Name); _objectStream.AddSupportedType(typeof(InitiateInputRequestEnvelope), typeof(InitiateInputRequest).Name); _objectStream.AddSupportedType(typeof(InitiateInputResponseEnvelope), typeof(InitiateInputResponse).Name); _objectStream.AddSupportedType(typeof(ConfigurationGetRequestEnvelope), typeof(ConfigurationGetRequest).Name); _objectStream.AddSupportedType(typeof(ConfigurationGetResponseEnvelope), typeof(ConfigurationGetResponse).Name); _objectStream.AddSupportedType(typeof(StockLocationInfoRequestEnvelope), typeof(StockLocationInfoRequest).Name); _objectStream.AddSupportedType(typeof(StockLocationInfoResponseEnvelope), typeof(StockLocationInfoResponse).Name); } // digital shelf _objectStream.AddSupportedType(typeof(ArticleInfoRequestEnvelope), typeof(ArticleInfoRequest).Name); _objectStream.AddSupportedType(typeof(ArticleInfoResponseEnvelope), typeof(ArticleInfoResponse).Name); _objectStream.AddSupportedType(typeof(ArticlePriceRequestEnvelope), typeof(ArticlePriceRequest).Name); _objectStream.AddSupportedType(typeof(ArticlePriceResponseEnvelope), typeof(ArticlePriceResponse).Name); _objectStream.AddSupportedType(typeof(ArticleSelectedMessageEnvelope), typeof(ArticleSelectedMessage).Name); _objectStream.AddSupportedType(typeof(ShoppingCartRequestEnvelope), typeof(ShoppingCartRequest).Name); _objectStream.AddSupportedType(typeof(ShoppingCartResponseEnvelope), typeof(ShoppingCartResponse).Name); _objectStream.AddSupportedType(typeof(ShoppingCartUpdateMessageEnvelope), typeof(ShoppingCartUpdateMessage).Name); _objectStream.AddSupportedType(typeof(ShoppingCartUpdateRequestEnvelope), typeof(ShoppingCartUpdateRequest).Name); _objectStream.AddSupportedType(typeof(ShoppingCartUpdateResponseEnvelope), typeof(ShoppingCartUpdateResponse).Name); if (configuration.EnableKeepAlive) { _keepAliveTimer = new Timer(); _keepAliveTimer.Elapsed += OnKeepAliveTimerElapsed; _keepAliveTimer.Interval = (configuration.KeepAliveInterval > 0) ? configuration.KeepAliveInterval * 1000 : 1000; _keepAliveTimer.Enabled = false; } }