jgauffin / Griffin.Framework

Application framework for Business Applications
http://griffinframework.net
168 stars 63 forks source link

Channel : Data Polling #49

Closed Tochemey closed 9 years ago

Tochemey commented 9 years ago

I have implemented the client using the ChannelTcpClient. I can send data to the upstream socket server and receive response. However I want to be reading some data via a different thread and at the same time sending data and reading response as usual. What I observe is that the polling thread has already remove my response data. So I went to the ChannelTcpClient ReceiveAync and I discovered that it uses a concurrent queue which means FIFO. I would like to know whether I am doing the right thing or there is a way to do polling as well as send request and receive response using ReceiveAsync.

jgauffin commented 9 years ago

You have to choose strategy if you want robustness. In your case I would probably code a client by using TcpChannel directly.

Something like this:

public class ClientExample
{
    private readonly TcpChannel _channel;

    public ClientExample()
    {
        MessageEncoding = Encoding.UTF8;

        _channel = new TcpChannel(
            new BufferSlice(new byte[65535], 0, 65535), 
            new YourEncoder(),
            new YourDecoder()) 
            {MessageReceived = OnMessage};
        _channel.Disconnected += OnDisconnect;
    }

    private void OnDisconnect(ITcpChannel channel, Exception exception)
    {
        if (Disconnected != null)
            Disconnected(this, EventArgs.Empty);
    }

    public void Connect(string remoteHost, int port)
    {
        //this client do not reconnect or try to connect again if the first attempt fails.
        //you need to code that by yourself.
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(remoteHost, port);
        _channel.Assign(socket);
    }

    private void OnMessage(ITcpChannel channel, object message)
    {
        //Will be invoked once a message arrives,
        //i.e. no need for polling
    }

    public void Send(string message)
    {
        _channel.Send(message);
    }

    public event EventHandler Disconnected;
}
Tochemey commented 9 years ago

Thank you for the quick answer. I think the suggested approach will suit my design.

Tochemey commented 9 years ago

I have implemented the way you suggested to me. However I get time to time socket disconnected whenever I wan to send message to the remote server. Any idea?

jgauffin commented 9 years ago

It's typically an encoder problem.

The channel should have an error callback that you can hook.

Tochemey commented 9 years ago

So How can I go about it any idea?

Tochemey commented 9 years ago

Hello Jonas,

I got a weird socketException while sending : Operation completed successfully. However he request has not been sent yet. I think something is wrong somewhere.

Tochemey commented 9 years ago

I run the app in debug mode from VS and I got the following exception after encoder has done its work at the TcpChannel sendCurrent method : $exception {"Cannot access a disposed object.\r\nObject name: 'System.Net.Sockets.Socket'."} System.ObjectDisposedException

jgauffin commented 9 years ago

provide a sample app reproducing the error.

Tochemey commented 9 years ago

Do you have any kind of pastebin or a place where I can show you the code?

Tochemey commented 9 years ago

Issue resolved. The problem was due to a string trimming.