-1

i am new in wcf service. still reading books to acquire knowledge. my company has many offices in our city but one head office. my company has one static IP. my company plan to host a wcf service in HQ server which can be reach by static IP over the internet and other office is connected each other by VPN. our company want me to develop a wcf service which will be using to handle company data among all the pc of HQ and also among all the pc of other offices. also people can outside will be able to connect to that wcf service.

company want that when any one try to connect to our service from HQ office then HQ lan will be used to connect to that service.

when any one try to connect to our service from our other offices then WAN or VPN connection will be used.

when any one try to connect to our service from other place or home then connection will be made through internet.

i am new in WCF so not being able to think how to design this kind of service with WCF which will be hosted in our HQ server which has static IP.

so guide me is there any tweak requited in coding or in config file where we specify various bindings.

i guess that we need to specify various binding in service config file. so just guide me how do i design or write the config file for service end which can be requested over the LAN, VPN and as well as internet. if possible give me a sample copy of config file for service end. thanks

Thomas
  • 33,544
  • 126
  • 357
  • 626
  • As long as your firewall and security allows communication on the ports you configure in your bindings, it will work. This question is too open to have a discrete answer. If this is new work, and using HTTP is ok, use Web API instead. http://stackoverflow.com/q/9348639/659190 – Jodrell Jun 18 '13 at 13:57

4 Answers4

1

LAN vs WAN vs VPN is at a too lower newtork level for WCF. Assuming you use say basicHttpBinding and host your WCF service in IIS that runs in the server in HQ that has a static IP, your internet users will be able to come to your service using the external IP (static IP) or the domain name if there is one. For intranet (LAN, WAN, etc), the users can use the internal IP, which you can get by pinging the server from within your network. Again assuming that the path between the computers where WCF will be consumed and where WCF service runs does not cut across firewalls and stuff, you can use a netTcp binding which can be slightly more performant but not worth the trouble if your organization has lots of red tape to opening ports and stuff if there are firewalls in between. Generally, 80 and 443 are not blocked.

  • just tell me do i need to handle this at wcf client end or server end in config file.can u please give me sample config entry for wcf service server end & client end. how do i detect that when client end will connect then it is using internet or lan ? – Mou Jun 18 '13 at 19:14
  • How it is typically done is as follows. When you create a service reference for your WCF service, the URI details are added to the config in the client side. For intranet clients, you will use the internal IP and for the external ones, you will use the static IP. It is possible to detect intranet versus internet but is a complex thing to do and the installation normally takes care of this part and the correct address is put in as part of installation. I'm assuming more like a thick client, .NET ofcourse. – Badrinarayanan Lakshmiraghavan Jun 19 '13 at 00:54
  • do u mean that user need to change Endpoint IP address in config before run from LAN? please discuss this issue. thanks – Thomas Jun 19 '13 at 07:06
  • No, I did not mean that. I meant the IP will be put into the config file at the time of installation by the installer. I was assuming same installation will not be used from both intranet and internet. If my assumption is not correct, it gets tricky. In that case, you will be better of connecting to the WCF endpoint without using svcutil and dynamically determine the address to use. For example, you can call Dns.GetHostAddresses("www.yourdomain.com") to see if it resolves and connect or fallback to your internal IP. – Badrinarayanan Lakshmiraghavan Jun 19 '13 at 09:30
  • @Thomas - Thomas I think you are asking the wrong question i.e. "how do I access WCF from my LAN?" The answer is you never want to use WCF over your lan because it is typically much slower than just getting data over ADO. Use the architecture I posted and you can make a service layer that gets data from WCF when necessary or from ADO (much faster). – Sam Jun 20 '13 at 17:49
1

We are working on a large project right now which I believe is similar to what you are working on. We have many users who will be accessing this app from their desktop PC's as well as their mobile devices. I designed a service layer that is very flexible that delivers optimal performance depending on if the user is local or remote (note that VPN = local). I cannot give you every detail due to lack of space but here are the big pieces:

Create three Visual studio projects (or one solution with three projects): 1) Your app, 2) A service project (.dll), 3) A WCF project.

Your service project is where the action is. In your service project, create an interface called something like IMyServices (this is standard WCF stuff):

[ServiceContract]
public interface IMyServices : IDisposable
{
    [OperationContract]
    IEnumerable<Allocation> GetAllocations();
}

Next, add a class like what you see below. I call it ServiceRouter because if the user is remote, it routes the request to WCF but if the user is local it just gets data using ADO over the LAN. Note that this class implments IMyServices.

public class ServiceRouter : IMyServices
{
    private readonly string ServiceURI;

    /// <summary>
    /// Routes data requests over the LAN if the client is connected locally or over a WCF service if the client is remote. Use this constructor to route data requests over the LAN.
    /// </summary>
    /// http://msdn.microsoft.com/en-us/library/ms735103.aspx
    /// 
    public ServiceRouter()
    {
        ServiceURI = null;
    }

    /// <summary>
    /// Routes data requests over the LAN if the client is connected locally or over a WCF service if the client is remote.
    /// </summary>
    /// <param name="serviceURI">Fully qualified URI of a WCF server if the user is remote.  Pass null if the user authenticated on the LAN (including using VPN)</param>
    /// http://msdn.microsoft.com/en-us/library/ms735103.aspx
    /// 
    public ServiceRouter(string serviceURI)
    {
        ServiceURI = serviceURI;
    }

    public IEnumerable<Allocation> GetAllocations()
    {
        IMyServices client = GetClient();
        var result = client.GetAllocations().ToList();
        CloseClient(client);
        return result;
    }

      #region WCFClient
    private IMyServices GetClient()
    {
        IMyServices _client;

        if (string.IsNullOrEmpty(ServiceURI))
            _client = new MYServices();
        else
        {
            _client = ChannelFactory<IMyServices>.CreateChannel(new BasicHttpBinding(), new EndpointAddress(ServiceURI));
            ((ICommunicationObject)_client).Open();
        }
        return _client;
    }

    private void CloseClient(IMyServices client)
    {
        ICommunicationObject wcfClient = client as ICommunicationObject;

        if (wcfClient != null)
        {
            if (wcfClient.State == CommunicationState.Faulted)
                wcfClient.Abort();
            else
                wcfClient.Close();
        }
        else
            ((IDisposable)client).Dispose();
    }
    #endregion
}

Next, in your service project, create a class for your services that implements IMyServices like this:

internal partial class MyServices : IMyServices
{
    public IEnumerable<Allocation> GetAllocations()
    {
        // access your db here
    }

Now here is how you you expose your services using WCF. You will need to configure your web.config and you will need to reference the .dll file from your service project.
In your WCF project add a WCF service like what you see below. Note this class inherits from ServiceRouter, which implements IMyService. The code below is the ONLY code in the WCF project! All this code does is create an instance of your ServiceRouter, passing it a null uri which tells it to get its data over the LAN. Your WCF server and you DB server need to be able to communicate over the LAN for this to work of course.

public class MyWCFService : MyServiceProject.ServiceRouter
{
    public MyWCFService() : base()
    { 
        // Since the WCF server is running on the local area network, this class only needs to create an instance of 
        // the service router in local mode and retrive the requested data.  WCF serializes the data and sends it
        // back over the wire.
    }
}

Here is a fragment of how your web.config might look:

<service name="MyWCFService" behaviorConfiguration="xxx">
        <endpoint address="" binding="basicHttpBinding" bindingNamespace="http://blah.com" contract="MyServiceProject.IMyServices"> 

In your app project, add a reference to your service .dll file. Look at your user's IP address and if it is local, use create instances of ServiceRouter passing null to the constructor. If the user is remote, pass the URI of your wcf server when you create insances of Service router: i.e. ServiceRouter router = new ServiceRouter(myServerName);

Sam
  • 1,621
  • 3
  • 22
  • 30
  • thanks for answer.u said " Look at your user's IP address and if it is local" so i just like to know how do i know that user is local by IP address or not ? – Mou Jun 18 '13 at 19:04
  • I suggest you look on stackoverflow for that as it is a different question and there many different ways to do it. There are no doubt many answers that are more detailed than what I can provide in these comments. – Sam Jun 18 '13 at 19:11
0

Thats a simple question of network configuration. Your service has one or more endpoints. So simple route the requests from the various networks to that/them.

  • just tell me do i need to handle this at wcf client end or server end in config file.can u please give me sample config entry for wcf service server end & client end. how do i detect that when client end will connect then it is using internet or lan ? – Mou Jun 18 '13 at 19:16
0

Your question is a bit "tl;dr" and open-ended but can I suggest you learn the "ABC's" of WCF endpoints: Address, Binding, Contract? If you'd like to use both HTTP and TCP for a single service endpoint can configure both binding types to the same endpoint.

From the article:

It is important to note is that these three elements are independent. A contract can support many bindings and a binding can support many contracts. A service can have many endpoints (contract bound to address) coexisting and available at the same time. So if you want to expose your service via HTTP and use SOAP 1.1 for maximum interoperability, and also want to expose it via TCP using a binary wire encoding for maximum performance, the two resulting endpoints can reside side-by-side on top of the very same service.

McArthey
  • 1,614
  • 30
  • 62