/// <summary> /// Closes the listener. /// </summary> private void InternalClose(object state) { TcpAsyncOperation <int> operation = (TcpAsyncOperation <int>)state; try { lock (m_lock) { while (m_channelQueue.Count > 0) { UaTcpReplyChannel channel = m_channelQueue.Dequeue(); channel.Abort(); } while (m_acceptQueue.Count > 0) { TcpAsyncOperation <IReplySessionChannel> waitingAccept = m_acceptQueue.Dequeue(); waitingAccept.Fault(StatusCodes.BadServerHalted); } Stop(); } operation.Complete(0); } catch (Exception e) { operation.Fault(e, StatusCodes.BadInternalError, "Could not close UA TCP listener."); } }
/// <summary cref="CommunicationObject.OnBeginOpen" /> protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { TcpAsyncOperation <int> operation = new TcpAsyncOperation <int>(Int32.MaxValue, callback, state); operation.Complete(0); return(operation); }
/// <summary cref="CommunicationObject.OnBeginClose" /> protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { TcpAsyncOperation <int> operation = new TcpAsyncOperation <int>(Utils.GetTimeout(timeout), callback, state); ThreadPool.QueueUserWorkItem(new WaitCallback(InternalClose), operation); return(operation); }
/// <summary cref="IReplyChannel.BeginTryReceiveRequest" /> public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state) { ThrowIfDisposedOrNotOpen(); try { TcpAsyncOperation <RequestContext> operation = new TcpAsyncOperation <RequestContext>(Utils.GetTimeout(timeout), callback, state); lock (m_lock) { if (m_requestQueue.Count > 0) { RequestContext request = m_requestQueue.Dequeue();; // Utils.Trace("Request Accepted (S): ChannelId={0}, RequestId={1}", this.m_channel.Id, request.RequestId); operation.Complete(request); return(operation); } m_operationQueue.Enqueue(operation); } return(operation); } catch (Exception e) { Utils.Trace(e, "BeginTryReceiveRequest Error"); throw; } }
/// <summary> /// Cancels all outstanding requests. /// </summary> private void InternalClose(object state) { TcpAsyncOperation <int> operation = (TcpAsyncOperation <int>)state; try { lock (m_lock) { while (m_requestQueue.Count > 0) { RequestContext context = m_requestQueue.Dequeue();; // Utils.Trace("Request Aborted: ChannelId={0}, RequestId={1}", this.m_channel.Id, context.RequestId); context.Abort(); } while (m_operationQueue.Count > 0) { TcpAsyncOperation <RequestContext> receiveOperation = m_operationQueue.Dequeue(); receiveOperation.Complete(null); } } operation.Complete(0); } catch (Exception e) { operation.Fault(e, StatusCodes.BadInternalError, "Could not close a UA TCP reply channel."); } }
/// <summary cref="CommunicationObject.OnAbort" /> protected override void OnAbort() { try { lock (m_lock) { while (m_requestQueue.Count > 0) { RequestContext context = m_requestQueue.Dequeue(); // Utils.Trace("Request Aborted: ChannelId={0}, RequestId={1}", this.m_channel.Id, context.RequestId); context.Abort(); } while (m_operationQueue.Count > 0) { TcpAsyncOperation <RequestContext> receiveOperation = m_operationQueue.Dequeue(); receiveOperation.Complete(null); } } } catch (Exception) { // ignore exceptions on abort. } }
/// <summary> /// Handles requests arriving from a channel. /// </summary> private void OnRequestReceived(TcpServerChannel channel, uint requestId, IServiceRequest request) { RequestContext context = null; lock (m_lock) { // create message. Message message = Message.CreateMessage( MessageVersion.Soap12WSAddressing10, Namespaces.OpcUaWsdl + "/InvokeService", new InvokeServiceBodyWriter(null, true)); string messageId = Utils.Format("urn:uuid:{0}", Guid.NewGuid()); // update headers. message.Headers.To = m_address.Uri; message.Headers.MessageId = new UniqueId(messageId); // add the raw object to the message properties. message.Properties.Add(MessageProperties.UnencodedBody, request); // create request. context = new RequestContext(channel, requestId, message, request); // Utils.Trace("Request Received: ChannelId={0}, RequestId={1}, RequestType={2}", this.m_channel.Id, requestId, request.BinaryEncodingId); } // notify any waiting threads. bool received = false; do { TcpAsyncOperation <RequestContext> operation = null; lock (m_lock) { if (m_operationQueue.Count == 0) { m_requestQueue.Enqueue(context); break; } // Utils.Trace("Request Accepted (A): ChannelId={0}, RequestId={1}", this.m_channel.Id, requestId); operation = m_operationQueue.Dequeue(); } try { received = operation.Complete(true, context); } catch (Exception e) { Utils.Trace(e, "Error receiving request"); received = false; } }while (!received); }
/// <summary cref="CommunicationObject.OnEndOpen" /> protected override void OnEndOpen(IAsyncResult result) { try { TcpAsyncOperation <int> operation = (TcpAsyncOperation <int>)result; operation.End(Int32.MaxValue); } catch (Exception e) { throw ServiceResultException.Create(StatusCodes.BadInternalError, e, "Could not open UA TCP channel factory."); } }
/// <summary cref="System.ServiceModel.Channels.RequestContext.EndReply(IAsyncResult)" /> public override void EndReply(IAsyncResult result) { try { TcpAsyncOperation <uint> operation = (TcpAsyncOperation <uint>)result; operation.End(Int32.MaxValue); } catch (Exception e) { Utils.Trace(e, "Could not send reply to request."); } }
/// <summary cref="CommunicationObject.OnEndClose" /> protected override void OnEndClose(IAsyncResult result) { try { TcpAsyncOperation <int> operation = (TcpAsyncOperation <int>)result; operation.End(Int32.MaxValue); } catch (Exception e) { m_fault = ServiceResult.Create(e, StatusCodes.BadInternalError, "Could not close UA TCP listener."); Utils.Trace(m_fault.ToLongString()); Fault(); } }
/// <summary> /// Closes the channel. /// </summary> private void InternalClose(object state) { TcpAsyncOperation <int> operation = (TcpAsyncOperation <int>)state; try { InternalClose(Int32.MaxValue); operation.Complete(0); } catch (Exception e) { operation.Fault(e, StatusCodes.BadInternalError, "Could not close UA TCP request channel."); } }
/// <summary cref="ChannelListenerBase{T}.OnEndAcceptChannel" /> protected override IReplySessionChannel OnEndAcceptChannel(IAsyncResult result) { try { TcpAsyncOperation <IReplySessionChannel> operation = (TcpAsyncOperation <IReplySessionChannel>)result; return(operation.End(Int32.MaxValue)); } catch (Exception e) { m_fault = ServiceResult.Create(e, StatusCodes.BadInternalError, "Error accepting a new UA TCP reply channel."); Utils.Trace(m_fault.ToLongString()); Fault(); return(null); } }
/// <summary> /// Opens the listener. /// </summary> private void InternalOpen(object state) { TcpAsyncOperation <int> operation = (TcpAsyncOperation <int>)state; try { lock (m_lock) { Start(); } operation.Complete(0); } catch (Exception e) { operation.Fault(e, StatusCodes.BadInternalError, "Could not start UA TCP listener."); } }
/// <summary cref="ChannelListenerBase{T}.OnBeginAcceptChannel" /> protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state) { TcpAsyncOperation <IReplySessionChannel> operation = new TcpAsyncOperation <IReplySessionChannel>(Utils.GetTimeout(timeout), callback, state); lock (m_lock) { if (m_channelQueue.Count > 0) { UaTcpReplyChannel channel = m_channelQueue.Dequeue(); Utils.Trace("Channel Accepted: Id={0}", channel.Id); operation.Complete(channel); return(operation); } m_acceptQueue.Enqueue(operation); } return(operation); }
/// <summary cref="System.ServiceModel.Channels.RequestContext.BeginReply(Message, TimeSpan, AsyncCallback, object)" /> public override IAsyncResult BeginReply(Message message, TimeSpan timeout, AsyncCallback callback, object state) { TcpAsyncOperation <uint> operation = new TcpAsyncOperation <uint>(Utils.GetTimeout(timeout), callback, state); IServiceResponse response = null; lock (m_lock) { if (m_channel != null) { response = (IServiceResponse)message.Properties[MessageProperties.UnencodedBody]; // Utils.Trace("Reply Sent: ChannelId={0}, RequestId={1}", this.m_channel.Id, m_requestId); m_channel.SendResponse(m_requestId, response); m_channel = null; } } operation.Complete(StatusCodes.Good); return(operation); }
/// <summary cref="IReplyChannel.EndTryReceiveRequest" /> public bool EndTryReceiveRequest(IAsyncResult result, out System.ServiceModel.Channels.RequestContext context) { context = null; TcpAsyncOperation <RequestContext> operation = (TcpAsyncOperation <RequestContext>)result; try { context = operation.End(Int32.MaxValue); return(true); } catch (TimeoutException) { return(false); } catch (Exception e) { m_fault = ServiceResult.Create(e, StatusCodes.BadInternalError, "Could not receive request from a UA TCP channel."); Utils.Trace(m_fault.ToLongString()); return(false); } }