Dailycode.info

Short solution for short problems

Grabbing the image from AXIS (P1346) Network Camera

Thanks to the wonderful API this camera has, you do not need DLL's or Active X controls. You can just get an image for example by the API.

Here an example to get the image from the camera using c# (this can be used in a service, web service or other applications):

Uri test = new Uri("http://192.0.0.100/jpg/image.jpg");

WebClient wc = new WebClient();

wc.Credentials = new NetworkCredential("MyUser", "MyPassW0rd");

wc.DownloadFile(test, @"C:\TakePicture\picFromWS.jpg");

wc.Dispose(); 

 

 


WCF: Which protocol to use? HTTP or TCP?

My overall conclusion of reading information and using both protocols is that you have to consider these to topics before choosing the protocol to use!

  • Are the services used internally or will they be used by external applications?
  • Is it an internet application?

When you answer yes to one of the previous questions, using the HTPP protocol will be the best choice. But when you develop a client server application for use within the company, use TCP.  TCP is in my opinion the best protocol to use when client and server use WCF and the application is running on a local network. The services can also be accessed by other applications running on this network and using WCF. So I believe that in many cases people just tend to HTTP without really looking why. Next I list a part from a Microsoft article, which explains this for you clear and brief:

When to Use HTTP Transport 

HTTP is a request/response protocol between clients and servers. The most common application consists of Web-browser clients that communicate with a Web server. The client sends a request to a server, which listens for client request messages. When the server receives a request, it returns a response, which contains the status of the request. If successful, optional data, such as a Web page, an error message, or other information is returned. For more information about the HTTP protocol, see HTTP - Hypertext Transfer Protocol.

The HTTP protocol is not connection-based—once the response is sent, no state is maintained. To handle multiple-page transactions, the application must persist any necessary state.

In WCF, the HTTP transport binding is optimized for interoperability with legacy non-WCF systems. If all communicating parties are using WCF, the TCP-based or named pipes-based bindings are faster. For more information, see NetTcpBinding and NetNamedPipeBinding.

When to Use the TCP Transport 

TCP is a connection-based, stream-oriented delivery service with end-to-end error detection and correction. Connection-based means that a communication session between hosts is established before exchanging data. A host is any device on a TCP/IP network identified by a logical IP address.

TCP provides reliable data delivery and ease of use. Specifically, TCP notifies the sender of packet delivery, guarantees that packets are delivered in the same order in which they are sent, retransmits lost packets, and ensures that data packets are not duplicated. Note that this reliable delivery applies between two TCP/IP nodes, and is not the same thing as WS-ReliableMessaging, which applies between endpoints, no matter how many intermediate nodes they may include.

The WCF TCP transport is optimized for the scenario where both ends of the communication are using WCF. This binding is the fastest WCF binding for scenarios that involve communicating between different machines. The message exchanges use the BinaryMessageEncodingBindingElement for optimized message transfer. TCP provides duplex communication and so can be used to implement duplex contracts, even if the client is behind network address translation (NAT).

 

Fast way to test your service is to open the visual studio command prompt and type in WCFTESTCLIENT This will open the WCFTestclient.exe and there you can test your endpoints.


Channel factory implementation (Easy client switch from http to tcp)

In an application I created, I am using WCF to make the connection from the process layer (Client side) to the business layer (Server side).

Since the environment started out using .Net Remoting, I initially used Transmission Control Protocol (TCP). But to make the best use of WCF, I enabled the possibility to switch to HTTP. WCF provides the ideal interface for this. Still some configuration needs to be done. On server side I handle everything via configuration files.

On client side however, I will not use the configuration file but  handle this in the program itself. Leaving a simple configuration switch (HTTP or TCP) in the configuration file to switch from one into the other protocol.

 

So I developed a class that handles this and initiates the proxy objects using the channel factory.

 

When the class is called (Class is cached in a Singleton class), this class will decide on which protocol to use to initiate the proxy classes:

 

For example:

To get some user information, I need to initiate the usermanger proxy class. The first check I will do is to check if the class is not yet initiated, if not, I will initiate it. Else I will pass the usermanger object.

The second check is to check the configuration, if we would use HTTP or TCP. In my case I get this during startup and put it in the singleton class property called CommunicationProtocol.  

 

public IUserManager UserManager
{
    get 
    {
        if (_userMgrProxy==null||(_userMgrProxy as ICommunicationObject).State != CommunicationState.Opened)
        {
            if (GenericSingleton<GeneralParams>.GetInstance().CommunicationProtocol == ProtocolMode.HTTP)
            {
                var binding = GetHttpBinding();
                _userMgrProxy = ChannelFactory<IUserManager>.CreateChannel(binding, new EndpointAddress(userEndPoint));
            }
            else
            {
                var binding = GetTcpBinding();
                _userMgrProxy = ChannelFactory<IUserManager>.CreateChannel(binding, new EndpointAddress(userEndPoint));
            }
        }
        return _userMgrProxy; 
    }
}

 

Depending on the communication protocol I will get the corresponding binding.

Below are functions to get the bindings.

 

private WSHttpBinding GetHttpBinding()
{
    return new WSHttpBinding
    {
        ReaderQuotas =
        {
            MaxDepth = 10000000,
            MaxArrayLength = 10000000,
            MaxBytesPerRead = 10000000,
            MaxNameTableCharCount = 10000000,
            MaxStringContentLength = 10000000
        },
        MaxReceivedMessageSize = 10000000,
        MessageEncoding = WSMessageEncoding.Mtom,
        MaxBufferPoolSize = 10000000
    };
}
 
private NetTcpBinding GetTcpBinding()
{
    return new NetTcpBinding
    {
        ReaderQuotas =
        {
            MaxDepth = 10000000,
            MaxArrayLength = 10000000,
            MaxBytesPerRead = 10000000,
            MaxNameTableCharCount = 10000000,
            MaxStringContentLength = 10000000
        },
        MaxReceivedMessageSize = 10000000,
        MaxBufferPoolSize = 10000000
    };
}

 

When the program starts up, I will initiate all proxy classes by default, the check when I call one of the proxies to check if its initiated or not is an extra check if for some reason the managers are called before being initialized.

Here the code I use to initialize the proxy manager objects:

 

public void InitChannels()
{
    //Set tcp or http
    if (GenericSingleton<GeneralParams>.GetInstance().CommunicationProtocol == ProtocolMode.HTTP)
    {
        var binding = GetHttpBinding();
        _animalMgrProxy = ChannelFactory<IAnimalManager>.CreateChannel(binding, new EndpointAddress(animalEndPoint));
        _configMgrpProxy = ChannelFactory<IConfigurationManager>.CreateChannel(binding, new EndpointAddress(configEndPoint));
        _studyMgrProxy = ChannelFactory<IStudyManager>.CreateChannel(binding, new EndpointAddress(studyEndPoint));
        _userMgrProxy = ChannelFactory<IUserManager>.CreateChannel(binding, new EndpointAddress(userEndPoint));
    }
    else
    {
        var binding = GetTcpBinding();
        _animalMgrProxy = ChannelFactory<IAnimalManager>.CreateChannel(binding, new EndpointAddress(animalEndPoint));
        _configMgrpProxy = ChannelFactory<IConfigurationManager>.CreateChannel(binding, new EndpointAddress(configEndPoint));
        _studyMgrProxy = ChannelFactory<IStudyManager>.CreateChannel(binding, new EndpointAddress(studyEndPoint));
        _userMgrProxy = ChannelFactory<IUserManager>.CreateChannel(binding, new EndpointAddress(userEndPoint));
    }

 

One last thing before I forget.  The endpoint URL’s are also collected from the configuration file. This is also done in this class and looks like this:

 

string animalEndPoint = GenericSingleton<GeneralParams>.GetInstance().CommunicationProtocolAddress+ "AnimalManager/AnimalMgr";
string configEndPoint = GenericSingleton<GeneralParams>.GetInstance().CommunicationProtocolAddress + "ConfigurationManager/ConfigurationMgr";
string studyEndPoint = GenericSingleton<GeneralParams>.GetInstance().CommunicationProtocolAddress + "StudyManager/StudyMgr";
string userEndPoint = GenericSingleton<GeneralParams>.GetInstance().CommunicationProtocolAddress + "UserManager/UserMgr";
string auditEndPoint = GenericSingleton<GeneralParams>.GetInstance().AuditProtocolAddress;

 

Then finally I can show the configuration on the client side:

 

  <appSettings>
    
    <!--<add key="CommunicationProtocol" value="HTTP"/>
    <add key="CPBaseAddress" value="http://localhost:7000/LabCollectWCFService/"/>-->
    
    <add key="CommunicationProtocol" value="TCP"/>
    <add key="CPBaseAddress" value="net.tcp://localhost:8000/LabCollectWCFService/"/>
    
    <add key="AuditBaseAddress" value="net.msmq://localhost/private/LabCollectAudit"/>

 

If I want to switch to HTTP I only need to uncomment the first to lines and comment the next 2 lines. That’s it.