0
votes

I am writing netTcpRelayBinding WCF service hosted in Windows Service. I feel my code is naive due to lack of experience in windows service development. This get called from Windows-Azure. Could you please help me review the code, and how I can improvise it:- we are using NLOG for logging.

My service throws exception (mentioned at end of question).

How should I :- 1. Define windows service dependency(Should it start before machine get connected to internet). 2. How it should be more fault tolerance, how can it start after some time interval.

namespace XYC.Service.WinServiceHost
    {
        public partial class XYCService : ServiceBase
        {
            private ServiceHost serviceHost = null;
            private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
            public One23InsightService()
            {
                // Name the Windows Service
                ServiceName = "XYCService ";
                const string logName = "Application";
                InitializeComponent();
                if (!System.Diagnostics.EventLog.SourceExists(ServiceName))
                {
                    System.Diagnostics.EventLog.CreateEventSource(ServiceName, logName);
                }
                EnLog.Source = ServiceName;
                EnLog.Log = logName;
            }

            protected override void OnStart(string[] args)
            {
                if (serviceHost != null)
                {
                    serviceHost.Close();
                }
                EnLog.WriteEntry(ServiceName + " Inside OnStart...");
                try
                {
                   serviceHost = new ServiceHost(typeof(InsightSrcDataService));

                    serviceHost.Faulted += HostFaulted;
                    serviceHost.UnknownMessageReceived += HostUnknownMessageReceived;

                    serviceHost.Open();
                    LogServiceInfo(serviceHost);
                    if (serviceHost.State != CommunicationState.Faulted)
                    {
                        EnLog.WriteEntry(ServiceName + " started successfully.");
                        EnLog.WriteEntry(ServiceName + " Automapping of entities are done successfully.");
                    }
                }
                catch (Exception ex)
                {
                    string msg = ServiceName + " failed to start. Exception Message:-" + ex.Message + (ex.InnerException != null ? ex.InnerException.Message : string.Empty);
                    EnLog.WriteEntry(msg);
                    Logger.LogException(NLog.LogLevel.Error, msg, ex);
                }
            }

            private void LogServiceInfo(ServiceHost host)
            {
                EnLog.WriteEntry(host.Description.ServiceType + "is up and running with these endpoints :");
                foreach (ServiceEndpoint se in host.Description.Endpoints)
                {
                    EnLog.WriteEntry(se.Address.ToString());
                }
            }

            private void HostUnknownMessageReceived(object sender, UnknownMessageReceivedEventArgs e)
            {
                EnLog.WriteEntry(ServiceName + " Inside UnknownMessageReceived.");
            }

            private void HostFaulted(object sender, EventArgs e)
            {
                EnLog.WriteEntry(ServiceName + " - Host Faulted.");
            }

            protected override void OnStop()
            {
                if (serviceHost == null) return;
                serviceHost.Close();
                serviceHost = null;
            }
        }
    }

Configuration

 <system.serviceModel>
    <services>
      <service name="XYC.Service.WCFNetTCPContract.DataService">
        <endpoint
          name="SrcWeb"
          address="sb://data.servicebus.windows.net/App/long-guid"
                  binding="netTcpRelayBinding"
                  contract="XYC.Service.Interface.IService"
                  bindingConfiguration="Hybrid"
                  behaviorConfiguration="sbTokenProvider" />

        <endpoint
          name="AdminServiceEndpoint"
          address="sb://serviceaddress.servicebus.windows.net/Admin/long-guid"
                  binding="netTcpRelayBinding"
                  contract="One234C.Service.AdminInterface.IOne23AdminService"
                  bindingConfiguration="Hybrid"
                  behaviorConfiguration="sbTokenProvider" />
      </service>
    </services>
    <bindings>
      <netTcpRelayBinding>
        <binding name="Hybrid" connectionMode="Hybrid" maxReceivedMessageSize="500000">
          <security mode="None" />
        </binding>
      </netTcpRelayBinding>
    </bindings>
    <behaviors>

      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="False" httpsGetEnabled="False" />
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="sbTokenProvider">
          <transportClientEndpointBehavior>
            <tokenProvider>
              <sharedSecret issuerName="owner" issuerSecret="xyc" />
            </tokenProvider>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <extensions>   
    </extensions>
  </system.serviceModel>

This sometimes throw following exception (I guess it is lacking Windows service dependency, I want this service to start after machine get connected to internet & sql server service is started).

  1. System.TimeoutException: The open operation did not complete within the allotted timeout of 00:00:00. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: Open timed out after 00:00:00 while establishing a transport session to net.tcp://xxx.servicebus.windows.net:9351/Src/guid/. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: Connecting to via net.tcp://xxx.servicebus.windows.net:9351/Src/guid/ timed out after 00:00:00. Connection attempts were made to 0 of 1 available addresses (). Check the RemoteAddress of your channel and verify that the DNS records for this endpoint correspond to valid IP Addresses. The time allotted to this operation may have been a portion of a longer timeout. at System.ServiceModel.Channels.SocketConnectionInitiator.CreateTimeoutException(Uri uri, TimeSpan timeout, IPAddress[] addresses, Int32 invalidAddressCount, SocketException innerException) at
  2. System.ArgumentException: issuerSecret is invalid. Parameter name: issuerSecret at Microsoft.ServiceBus.SharedSecretTokenProvider.DecodeSecret(String issuerSecret) at Microsoft.ServiceBus.SharedSecretTokenProvider..ctor(String issuerName, String issuerSecret) at Microsoft.ServiceBus.Configuration.TokenProviderElement.CreateTokenProvider() at Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement.CreateBehavior() at System.ServiceModel.Description.ConfigLoader.LoadBehaviors[T](ServiceModelExtensionCollectionElement1 behaviorElement, KeyedByTypeCollection1 behaviors, Boolean commonBehaviors) at System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress, Boolean skipHost) at System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, ServiceElement serviceSection) at System.ServiceModel.ServiceHost.ApplyConfiguration() at System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses) at System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses) at One234C.Service.WinServiceHost.One23InsightService.OnStart(String[] args) issuerSecret is invalid.
2

2 Answers

0
votes

Well the second error means that the issuer key for the namespace you are using is incorrect. You may need to check to make sure you are using the correct key.

0
votes

Looks like a bug in implementation of the the NetTCPRelaybinding. I am having same issue as well. I relay section of the Servicebus, I can see the service being displayed but the relaytype is None.