none
Cannot generate proxy on net.tcp if the contract is too big RRS feed

  • Question

  • Hi

    I have a wcf service that works perfectly by using the binding HTTP (web service mode): On the client application developement, I use SvcUtil to generate my proxy; everything works perfectly fine.

     

    Then I decided to use net.tcp binding. I built a host application. My server starts without any problem. But I can't generate the proxy anymore. I have an error which tells me that the server stopped the connection. At the server side, I changed the setup file so that WCF logs the activity in a file, and I restarted the manipulation. In the log file, at the moment I tried to produce my proxy, it's written that the server closed the connection because the answer timeout has expired and that the connection was closed because of it. I tried many things, and step by step, by commentings some parts of the service contract, I eventually succeeded to generate a proxy. I tried many combinations to find was was the part of the contract that could be the reason of the problem, and I concluded that nothing was a problem for the net.tcp binding. The problem was actually the size of the contract. For example (in much bigger):

     

    interface IMyContract

    {

    Truc GetTruc(int id);

    Blah GetBlah(int id);

    }

    ==> doesn't work

     

    interface IMyContract

    {

    //Truc GetTruc(int id);

    Blah GetBlah(int id);

    }

    ==> works!!!

     

    interface IMyContract

    {

    Truc GetTruc(int id);

    //Blah GetBlah(int id);

    }

    ==> works!!!

     

    To summarize:

     * The full contract works fine in http binding

     * The full contract cannot have a proxy produced in net.tcp binding

     * All parts of the contact can have a proxy produced in net.tcp binding

     

    I thought of producing several contracts BUT:

     * they all have common data contracts

     * I would need to make two hosts. I want my server to be easy to maintain and administrate.

     

    I've seen that some developpers had the same issue whereas a contract returned a typed Dataset. I guess that they have this issue because metadata that represent a typed Dataset is quiet big. For information, I don't have any dataset in my contract. My contract contains 24 datatypes, that make reference to eachothers, and almost 50 methods.

    I DON'T HAVE ANY DATASET IN MY CONTRACT, only strongly typed objects.

     

    Is there a way to solve my issue?

    Saturday, October 13, 2007 12:09 PM

Answers

  • * I want to use net.tcp binding

    >Nothing wrong with that ... Though normally its wise to publish the wsdl via http.

     

     * I DON'T HAVE ANY DATASET (typed or not) IN MY CONTRACT; I only have strongly typed objects.

    >Sory about that

     

     * it works perfectly fine if the service is hosted in a web service

    >Even with a tcp end point ? Or are you talking about an asmx (v1.0) web service ?

     

     * it doesn't work if the service is hosted on net.tcp binding: the problem is that it's impossible to create the proxy.

     

     * The proxy produced against http binding is not compatible if I use it for net.tcp binding

    >This makes no sense to me ... I have used http binding proxies many times and changed it to a tcp channel and its fine,  There must be sonething wrong here.

     

    >In the Beta that was all you could do and i still do it this way . I think in the RC and final release the supported generating a proxy over tcp but originally you created the proxy via an http exposed endpoint and it could then be used by a tcp channel.

     

     * I don't want to reduce the mane of my functions and properties, that will make my service unusable by other developers. Moreover, later, I'll have to add new methods on this service. So even if I do that, sooner or later, I'll have the same issue.

     

    > not saying it wont be an issue adding more  just bad practice to have many methods.

     

     * My functions receive as parameters objects that are responses of other functions and so on; that means that I cannot separate it in several services. Moreover, I don't wanna have several services; I want only one. I considered already of splitting in several services, but I can't; most of my datacontract are shared. And even if a miracle make that I can split it, it will be complicated for developpers who will use the service, to find where is what.

    > I dont know your implementation but in most cases it can be done.. Note having simpler services can make things easier to maintain. In one case i have had a shared dll with bLL which was used by 6 services but hosted in one app. , this now allows us to go to a better design by breaking things up .

     

    By the way 24 datatypes is not a lot which is why im questioning things . I normally have 5-15  methods and say 10-50 datatypes. Some have many more..

     

     * I don't wan't to expose technical keys on my service.

    > Always good

     

    To summarize, there is no way to change the timeout of the mex binding for net.tcp????????

     

    Have a look at

    http://blogs.msdn.com/drnick/archive/2006/08/23/713297.aspx

    http://blogs.msdn.com/drnick/archive/2006/08/31/733173.aspx

     

    Regards,

     

    Ben

     

    Monday, October 15, 2007 6:28 AM

All replies

  • > Not sure if your client is timing out or the fornatter/Serializer us gagging ,

     

     

    I thought of producing several contracts BUT:

     * they all have common data contracts

    > Normally you can  seperate some contracts in some and some on the other. I nornally like mapping my operations to use cases  and about 5-10 operations. 20 in rare cases.

     

     * I would need to make two hosts. I want my server to be easy to maintain and administrate.

     

    > This is a hosting question , it should be noted that an application eg windows services or IIS can host 2 services in the same app  meaning no difference in admin.  However it can be good for Larger applications to seperate it so you can upgrade one component withotu affecting the other.

     

    >Also  note you can generate the wsdl (via http) and expose it via a file.

     

    >Its worth noting that datasets are serialized via IxmlSerializable which is an xml serializtion , when using a binary formatted channel it will first serialize it as xml and then have a post processing step , hence its likley that a  xml non binary channel may  have a lower serialization time.

     

     also from ..

    http://msdn2.microsoft.com/en-us/library/ms979193.aspx In particular its good to copy only the tables you need for a method to a new dataset .

     

    Improving DataSet Serialization

    Many applications pass DataSet objects between remote tiers, although doing so incurs a significant serialization overhead and can cause your application to not meet its performance goals.

    DataSets are complex objects with a hierarchy of child objects, and as a result, serializing a DataSet is a processor-intensive operation. Also, DataSet objects are serialized as XML even if you use the binary formatter. This means that the output stream is not compact.

    There are a number of techniques that you can use to improve DataSet serialization performance.

     

    Using Column Name Aliasing

    You can try aliasing long column names with shorter names to reduce the size of the serialized data. The following example shows how you can use aliases for column names by using the as keyword in your SQL.

    DataSet objDataset = new DataSet("Customers");
    SqlDataAdapter myAdapter = new SqlDataAdapter("Select CustomerId as C,CompanyName as D,ContactName as E,ContactTitle as F from Customers",myConnection);
    myAdapter.Fill(objDataset);
    Stream serializationStream = new MemoryStream(byteData,0,byteData.Length,true,true);
    serializationStream.Position=0;
    iBinForm.Serialize(serializationStream,objDataset);
    

    Avoiding Serializing Multiple Versions of the Same Data

    As soon as you make changes to the data in a DataSet you begin to maintain multiple copies of the data. The DataSet maintains the original data along with the changed values. If you do not need to serialize new and old values, call AcceptChanges before you serialize a DataSet to reset the internal buffers. Depending upon the amount of data held in the DataSet and the number of changes you make, this can significantly reduce the amount of data serialized. This approach is shown in the following code example.

    // load some data into the dataset
    customers.Fill(northwind, "Customers");
    orders.Fill(northwind, "Orders"); 
    // ... modify the data 
    northwind.AcceptChanges();
    // accept the changes made and flush the internal buffers 
    // ... serialize the dataset 
    

    Reducing the Number of DataTables Serialized

    If you don't need to send all of the DataTables contained in a DataSet, consider copying the DataTables you need to send into a separate DataSet. This will reduce the amount of data serialized by reducing the DataTables processed and by initializing the change buffers that are used by the DataView.

    customers.Fill(northwind, "Customers");
    orders.Fill(northwind, "Orders"); 
    //… use or modify some data 
    DataSet subset = new DataSet();
    // copy just the customer DataTable 
    subset.Tables.Add( northwind.Tables["customers"].Copy());
    // ... serialize the subset DataSet
    

    Overriding DataSet for Binary Serialization

    By default, DataSets are serialized as XML even if you use the BinaryFormatter. This leads to large serialization data streams. To produce a more compact output format, you can consider overriding the DataSet class and implementing your own serialization.

     

    Regards,

     

    Ben

     

     

     

     

    Regards,

     

    Ben

     

    Sunday, October 14, 2007 2:38 AM
  • I think U didn't follow my explanation:

     * I want to use net.tcp binding

     * I DON'T HAVE ANY DATASET (typed or not) IN MY CONTRACT; I only have strongly typed objects.

     * it works perfectly fine if the service is hosted in a web service

     * it doesn't work if the service is hosted on net.tcp binding: the problem is that it's impossible to create the proxy.

     * The proxy produced against http binding is not compatible if I use it for net.tcp binding

     * I don't want to reduce the mane of my functions and properties, that will make my service unusable by other developers. Moreover, later, I'll have to add new methods on this service. So even if I do that, sooner or later, I'll have the same issue.

     * My functions receive as parameters objects that are responses of other functions and so on; that means that I cannot separate it in several services. Moreover, I don't wanna have several services; I want only one. I considered already of splitting in several services, but I can't; most of my datacontract are shared. And even if a miracle make that I can split it, it will be complicated for developpers who will use the service, to find where is what.

     * I don't wan't to expose technical keys on my service.

     

    To summarize, there is no way to change the timeout of the mex binding for net.tcp????????

    Sunday, October 14, 2007 11:42 AM
  • You may try to create a proxy without exposing a mex endpoint for it. If you able to provide a proxy to the clients rather than let them generate it - this could be a suitable option. Details here and here .

    On the other hand, you may specify timeout for the mex endpoint just as for the regular endpoint. Doesn't it works for you?

     

    Regars,

           Alex Pinsker

           http://alexpinsker.blogspot.com
    Sunday, October 14, 2007 9:07 PM
  • * I want to use net.tcp binding

    >Nothing wrong with that ... Though normally its wise to publish the wsdl via http.

     

     * I DON'T HAVE ANY DATASET (typed or not) IN MY CONTRACT; I only have strongly typed objects.

    >Sory about that

     

     * it works perfectly fine if the service is hosted in a web service

    >Even with a tcp end point ? Or are you talking about an asmx (v1.0) web service ?

     

     * it doesn't work if the service is hosted on net.tcp binding: the problem is that it's impossible to create the proxy.

     

     * The proxy produced against http binding is not compatible if I use it for net.tcp binding

    >This makes no sense to me ... I have used http binding proxies many times and changed it to a tcp channel and its fine,  There must be sonething wrong here.

     

    >In the Beta that was all you could do and i still do it this way . I think in the RC and final release the supported generating a proxy over tcp but originally you created the proxy via an http exposed endpoint and it could then be used by a tcp channel.

     

     * I don't want to reduce the mane of my functions and properties, that will make my service unusable by other developers. Moreover, later, I'll have to add new methods on this service. So even if I do that, sooner or later, I'll have the same issue.

     

    > not saying it wont be an issue adding more  just bad practice to have many methods.

     

     * My functions receive as parameters objects that are responses of other functions and so on; that means that I cannot separate it in several services. Moreover, I don't wanna have several services; I want only one. I considered already of splitting in several services, but I can't; most of my datacontract are shared. And even if a miracle make that I can split it, it will be complicated for developpers who will use the service, to find where is what.

    > I dont know your implementation but in most cases it can be done.. Note having simpler services can make things easier to maintain. In one case i have had a shared dll with bLL which was used by 6 services but hosted in one app. , this now allows us to go to a better design by breaking things up .

     

    By the way 24 datatypes is not a lot which is why im questioning things . I normally have 5-15  methods and say 10-50 datatypes. Some have many more..

     

     * I don't wan't to expose technical keys on my service.

    > Always good

     

    To summarize, there is no way to change the timeout of the mex binding for net.tcp????????

     

    Have a look at

    http://blogs.msdn.com/drnick/archive/2006/08/23/713297.aspx

    http://blogs.msdn.com/drnick/archive/2006/08/31/733173.aspx

     

    Regards,

     

    Ben

     

    Monday, October 15, 2007 6:28 AM