dotnet / MQTTnet

MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). The implementation is based on the documentation from http://mqtt.org/.
MIT License
4.51k stars 1.07k forks source link

Can't dispose the socket #872

Closed FarshadX closed 4 years ago

FarshadX commented 4 years ago

Describe your question

I'm using mqttnet server to initiate a local MQTT server and receive messages in UWP programming. I initialize the server on a specific port(6616) In my scenario, I wanna stop the mqttserver and start it again after a while. I use await mqttServer.StopAsync() to stop the mqttserver. After starting the mqttserver again the application will terminate with the following exception:

System.Runtime.InteropServices.COMException: 'Only one usage of each socket address (protocol/network address/port) is normally permitted.
Only one usage of each socket address (protocol/network address/port) is normally permitted.

so it seems that the server wasn't stopped perfectly or the socket port wasn't disposed correctly, I checked my active connection with netstat command in cmd after stopping the server and find out the related socket(port) wasn't disposed. Did I do something wrong? Is there any solution?

IMqttServer mqttServer = new MqttFactory().CreateMqttServer();
public async bool StopServer()
{
     await mqttServer.StopAsync();
}
public async bool StartServer()
{
    StartMQTTServer();
}
public async void StartMQTTServer()
{
    DataCaptureService dataCaptureService = new DataCaptureService();
    mqttServer = new MqttFactory().CreateMqttServer();
    var options = new MqttServerOptionsBuilder().WithDefaultEndpointPort(6616); //Port

    await mqttServer.StartAsync(options.Build());  //The error occured here

    mqttServer.ApplicationMessageReceivedHandler = new 
        MqttApplicationMessageReceivedHandlerDelegate(async e =>
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    //Server Listener is waiting to get a message from local client
                    dataCaptureService.InsertUnparsedMQTTData(e.ApplicationMessage.ConvertPayloadToString(), DateTime.UtcNow);
                });
            });
 }

Which project is your question related to?

SeppPenner commented 4 years ago

I'm not sure, but

public async bool StartServer()
{
    StartMQTTServer();
}

shouldn't even work...

You're using a bool StartServer() method which returns bool, but public async void StartMQTTServer() returns void.

I would use it like this:

public async bool StartServer()
{
    try
    {
        await StartMQTTServer();
        return true;
    }
    catch
    {
        return false;
    }
}
public async Task StartMQTTServer()
{
    // ... Whatever
}
SeppPenner commented 4 years ago

Possible duplicate of https://github.com/chkr1011/MQTTnet/issues/494. Might be fixed in https://github.com/chkr1011/MQTTnet/pull/940.

chkr1011 commented 4 years ago

@FarshadX Please set the ReuseAddress property in the server options before starting the server.

SeppPenner commented 4 years ago

@FarshadX Specifically, set new MqttServerOptionsBuilder().Build().TlsEndpointOptions.ReuseAddress = true;, check out my example project under https://github.com/mqttnettest/Issue872Test as well.

deveshspraxa commented 4 years ago

Not able to use the https://github.com/mqttnettest/Issue872Test

SeppPenner commented 4 years ago

@deveshspraxa What's the issue?