DEV Community

Dmitry
Dmitry

Posted on

WitCom and Discovery

As discussed in previous articles, WitCom is inspired by WCF—not necessarily in its internal implementation, but in terms of developer experience and capabilities. One of the key technologies that WCF offered “out of the box” was Discovery. With Discovery, a server could announce its presence on a local network via UDP multicast, allowing clients to learn about available services and decide whether to connect. WitCom offers a similar feature, enhancing flexibility in dynamic environments.

Server-Side Discovery

To enable Discovery during server creation, simply include the appropriate option when building your WitCom server. For example:

var server = WitComServerBuilder.Build(options =>
{
    options.WithService(ExampleService);
    options.WithNamedPipe(address);
    options.WithEncryption();
    options.WithJson();
    options.WithDiscovery();
    options.WithAccessToken(ACCESS_TOKEN);
    options.WithTimeout(TimeSpan.FromSeconds(1));
    options.WithName(dialog.ServerName);
    options.WithDescription(dialog.ServerDescription);
});
Enter fullscreen mode Exit fullscreen mode

By default, if you do not specify custom parameters, a one-time “Hello” message is sent at server startup and a “Goodbye” message when it shuts down. These messages are broadcast to the standard multicast address 239.255.255.250 and port 3702.

You can also customize the Discovery parameters:

Custom Address and Port

options.WithDiscovery(host, port);
Enter fullscreen mode Exit fullscreen mode

Periodic Announcements

To continuously remind clients that the server is still available, you can specify a repeat interval:

options.WithDiscovery(host, port, TimeSpan.FromSeconds(10));
Enter fullscreen mode Exit fullscreen mode

or simply:

options.WithDiscovery(TimeSpan.FromSeconds(10));
Enter fullscreen mode Exit fullscreen mode

In this case, while the server is running and accepting connections, a Discovery message is sent every 10 seconds.

The Discovery message contains critical information such as:

  • The transport type and connection settings (for example, the name of the memory-mapped file, the named pipe, the TCP port, or the WebSocket URL).
  • The server’s name and description (if provided during initialization).

Client-Side Discovery

On the client side, to receive Discovery messages, you need to create a Discovery client. For instance:

DiscoveryClient = WitComClientBuilder.Discovery(options =>
{
    options.WithLogger(Logger);
    options.WithJson();
    options.WithAddress(host, port);
});
Enter fullscreen mode Exit fullscreen mode

Note: Ensure that you specify the same serializer as on the server (JSON is used by default). If no address is provided, the default multicast address (239.255.255.250) and port (3702) are used.

Next, subscribe to the event that is fired upon receiving a Discovery message:

DiscoveryClient.MessageReceived += OnMessageReceived;
Enter fullscreen mode Exit fullscreen mode

Then start listening:

DiscoveryClient.Start();
Enter fullscreen mode Exit fullscreen mode

Once a Discovery message is received, you can build a WitCom client by selecting the appropriate transport based on the content of the message. For example:

var client = WitComClientBuilder.Build(options =>
{
    options.WithTransport(SelectedMessage);
    options.WithEncryption();
    options.WithJson();
    options.WithAccessToken(ACCESS_TOKEN);
    options.WithLogger(Logger);
    options.WithTimeout(TimeSpan.FromSeconds(1));
});
Enter fullscreen mode Exit fullscreen mode

Here’s an example helper method that configures the transport according to the Discovery message:

public static WitComClientBuilderOptions WithTransport(this WitComClientBuilderOptions me, DiscoveryMessage message)
{
    if (message.Data == null)
        throw new ArgumentOutOfRangeException(nameof(me), me, null);

    if (message.IsMemoryMappedFile())
        return me.WithMemoryMappedFile(message);

    if (message.IsNamedPipe())
        return me.WithNamedPipe(message);

    if (message.IsTcp())
        return me.WithTcp("localhost", message);

    if (message.IsWebSocket())
        return me.WithWebSocket("ws://localhost", message);

    throw new ArgumentOutOfRangeException(nameof(me), me, null);
}
Enter fullscreen mode Exit fullscreen mode

Examples and Further Resources

You can find detailed examples of using Discovery with WitCom on GitHub: WitCom Discovery Examples

References and Resources

For more in-depth information on WitCom, please refer to the following resources:

WitCom Overview
WitCom and Blazor WebAssembly
WitCom and Static Proxy
Inter-process Communication with WitCom
WitCom Project Root

Top comments (0)