Communication between Wcf service to Windows Service?

214 views
Skip to first unread message

Cédric CONTE

unread,
Dec 31, 2014, 9:29:12 AM12/31/14
to netm...@googlegroups.com

Hi Everyone,

We have a Wcf Service hosting in IIS which receive http requests from many clients (web browser).

The Wcf Service has to do many operations:

  • Records data into the database
  • Send Emails
  • Send SMS
  • Check FTP server 
  • Collect files

So, to relieve our Wcf Service (which not adapted for long running thread work) we have decided to use the Wcf Service to catch only the http request and send a message (with NetMQ) to a windows service in order to do the long work.

To evaluate the architecture, we have written a small demo (see below the code) but we are facing an issue.

Actually, after several http requests send from client browsers to the Wcf Service, the Wcf Service raise the following error:

"Only one usage of each socket address (protocol/network address/port) is normally permitted”

I guess, We don’t use well the NetMq library. Is someone can advise us to do it ? Thanks in advance.

The Wcf Service code:

public class DataTrackService : IDataTrackService
   
{

       
public void PostData(Stream input)
       
{
           
using (StreamReader reader = new StreamReader(input, Encoding.UTF8))
           
{
               
string workload = reader.ReadToEnd();
               
try
               
{
                   
Task.Factory.StartNew(() =>
                   
{
                       
using (NetMQContext ctx = NetMQContext.Create())

                       
{
                           
using (var sender = ctx.CreatePushSocket())

                           
{
                                sender
.Bind("tcp://*:5557");
                                sender
.Send(workload);
                           
}

                       
}

                   
});
               
}
               
catch (Exception ex)

               
{
                   
throw ex;
               
}
               
return;
       
}

     
}


The window service code (simulated by console application) :

static void Main(string[] args)       {
 
           
using (NetMQContext ctx = NetMQContext.Create())
           
{
               
//socket to receive messages on
               
using (var receiver = ctx.CreatePullSocket())
               
{
                   receiver
.Connect("tcp://localhost:5557");
 
                   
//process tasks forever
                   
while (true)
                   
{
                       
string workload = receiver.ReceiveString();
 
                       
Console.WriteLine("receiver : " + workload);
 
                   
}
               
}
           
}
 
       
}

Best regards,

Cedric

Matthew Darnall

unread,
Dec 31, 2014, 9:59:57 AM12/31/14
to Cédric CONTE, netm...@googlegroups.com
Only one sender can be bound to the tcp://*:5557 at any given time.  My guess is you have two requests come in at the same time and the second one can't bind since the first is still bound.

Create the context and the sender in the WCF service outside of the PostData function in its own thread.  Have that thread just read from a BlockingCollection and send a message when it receives something. The Postdata function can just add something to the BlockingCollection so it stays multithreaded.



--
You received this message because you are subscribed to the Google Groups "netmq-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netmq-dev+...@googlegroups.com.
To post to this group, send email to netm...@googlegroups.com.
Visit this group at http://groups.google.com/group/netmq-dev.
For more options, visit https://groups.google.com/d/optout.

Doron Somech

unread,
Dec 31, 2014, 10:15:20 AM12/31/14
to Matthew Darnall, Cédric CONTE, netm...@googlegroups.com
I agree with Matthew regarding the port is probably already taken, also for TCP it's can take a little time until the resource is freed.

Why do you always create the socket in the webserver? why not create it once when the website starts? you can use multiple patterns for sending information from asp.net app, try to read:

Cédric CONTE

unread,
Dec 31, 2014, 10:25:04 AM12/31/14
to netm...@googlegroups.com
Thx a lot dnallicus,

You are right. I have followed your advices and initialize the netmq context and socket inside the wcf service contructor.
I have also set InstanceContextMode and ConcurrencyMode (wcf ServiceBehavior) to single in order to manage thread and Concurrency but the next step will be to implement the BlockingCollection and have a real multi-thread service.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class DataTrackService : IDataTrackService
{
 
    private NetMQContext _context;
    private NetMQSocket _socket;
 
 
    public DataTrackService()
    {
        _context = NetMQContext.Create();
        _socket = _context.CreatePushSocket();
        _socket.Bind("tcp://*:5557");
    }
 
    public void PostData(Stream input)
    {
        using (StreamReader reader = new StreamReader(input, Encoding.UTF8))
        {
            string workload = reader.ReadToEnd();
            LoggerManager.Log(workload, LoggerManager.TypeLog.Service, LoggerManager.CriticityLog.Info);
 
            try
            {
                Task.Factory.StartNew(() =>
                {
                    _socket.Send(workload);
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return;
        }
    }
 
}
Reply all
Reply to author
Forward
0 new messages