1

Given

I am using XSockets 3.0.6 which I think is the latest stable version. Under MS.NET the behavior is as expected. On Ubuntu 14.04 and Mono 3.6.1 though the server has some kind of delays before sending messages to clients.

Problem

On MS.NET when I type a string in the client and send it, all clients are immediately notified. On Mono though message is received by the server and clients were not notified immediately. With only 1 message I waited for 5 minutes and clients were still not notified. When messages become 5-6 then all clients become notified about all messages at once. It seems like the server uses some kind of buffering but conditionally - depending on the .NET runtime, which is very strange.

Question

Am I doing something wrong? How to change the code so that all clients are immediately notified as in MS.NET?

Code

I followed (and slightly modified) the quick start example as follows...

Server

Initialization

using (var container = Composable.GetExport<IXSocketServerContainer>())
{
    container.StartServers();

    foreach (var server in container.Servers)
    {
        Console.WriteLine(server.ConfigurationSetting.Endpoint);
    }

    Console.Write("Started! Hit 'Enter' to quit.");
    Console.ReadLine();

    container.StopServers();
}

Custom controller

public class CustomController : XSocketController
{
    public override void OnMessage(ITextArgs textArgs)
    {
        Console.WriteLine ("No delay = {0}", this.Socket.Socket.NoDelay);
        if (!this.Socket.Socket.NoDelay)
        {
            Socket.Socket.NoDelay = true;
        }

        Console.WriteLine("Received {0} about {1}.", textArgs.data, textArgs.@event);
        this.SendToAll(textArgs);
    }
}

Client

var client = new XSocketClient("ws://127.0.0.1:4502/CustomController", "*");

client.OnOpen += (sender, eventArgs) => System.Console.WriteLine("OPEN");
client.Bind("foo", message => System.Console.WriteLine(message.data));
Thread.Sleep(1000);
client.Open();

string input;
System.Console.WriteLine("Type 'quit' to quit and any other string to send a message:");
do
{
    input = System.Console.ReadLine();
    if (input != "quit")
    {
        client.Send(input, "foo");
    }
} while (input != "quit");
Community
  • 1
  • 1
Ceco
  • 1,586
  • 3
  • 16
  • 23

2 Answers2

1

I experienced this my self when running XSockets on a raspberry pi. After some investigation I realized that it had to do with the fact that the pi is single core and that internal queue did not send the message out until 5 messages was sent in.... Then all messages was sent out.

How many cores does your computer have ?

This issue is resolved in 4.0 (in alpha right now)

Edit: I have only had this issue on single core machines with Mono, on my Mac Book Air everything works great on Mono

Uffe
  • 2,275
  • 1
  • 13
  • 9
  • I am using Ubuntu 14.04 as a virtual machine. It has 3 cores. – Ceco Jun 24 '14 at 05:59
  • I wrote some simple multi-threaded code and it successfully utilizes all CPU cores. – Ceco Jun 24 '14 at 06:30
  • Very interesting! So let me rephrase. It worked fine on 4 cores, but not on 1 core... The issue occurs on the single core machine when we use GetConsumingEnumerable on a blocking collection. I do not have any machine with < 4 cores so I cant test this :( Would be interesting to see if 4.0 alpha behaves the same way for you on 3 cors. Do you want it? If so send me an email uffe@xsockets.net – Uffe Jun 24 '14 at 06:37
  • XSockets worked fine only on my host OS which is Windows using MS.NET. In my virtual Ubuntu machine it was delaying client notifications as explained. The simple multi-threaded code I wrote was not related to XSockets - I did that just to make sure that a mono process can utilize all cores available and there's nothing wrong with my mono setup. Also, I rebooted my VM and assigned to it 4 (instead of 3) cores - the problem still persists. – Ceco Jun 24 '14 at 06:47
  • So, to sum up. Works on MS.NET and Mono on OSX, but not on Mono + Ubuntu. Will look into it. But there will probably not be a 3.0.7 (unless somone really, really, really needs it). If the errors exists on 4.0 alpha thats where the fix will be. – Uffe Jun 24 '14 at 06:54
  • 1
    I haven't tested it on OSX as I don't have a Mac, just Mono + Ubuntu. Also, it is quite reasonable to move on to 4.0 instead of 3.0.7 as you said. I sent you an email about 4.0 – Ceco Jun 24 '14 at 06:59
  • The problem is fixed in latest XSockets 4.0 alpha 2. – Ceco Jun 30 '14 at 14:27
1

It looks that the Naggle Algorithm is not disabled in XSockets. In System.Net.Sockets you can disable Naggle algorithm by setting Socket.NoDelay property to true. I'm not familiar with XSockets, but if you can get underlying System.Net.Sockets.Socket class from XSockets, you can set this property to true and avoid the sending delay.

Sergey Zhukov
  • 1,342
  • 1
  • 13
  • 24
  • The socket in both MS.NET and Mono has `NoDelay` set to `false` and still the behavior is different. Setting the property to `true` in Mono has no effect. – Ceco Jun 24 '14 at 11:24
  • Behaviour of `NoDelay=false` is different, because OSes work differently with TCP buffering. Even mono on Ubuntu and mono on Debian have different behaviour with `NoDelay=false`. Do you set `NoDelay=true` before sending data from the server? – Sergey Zhukov Jun 24 '14 at 11:58
  • By behavior I meant the **whole example** behavior. Although I get your point. When the first client -> server call is made `NoDelay=false`. I set it to `true` and then I send data from the server to all the clients. Subsequent client -> server calls from the same client have `NoDelay=true`. And the problem persists. I've updated my question to illustrate what the code looks like - the addition is in the `CustomController` class. – Ceco Jun 24 '14 at 13:26