We are trying to define a Service Fabric Stateless Service which listeners for UDP data.
We are working with Microsoft who have said that it IS supported and that I
I have Udp Working as a stateless service. This is the Code:
UdpService.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Fabric;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
namespace UdpService
{
///
/// An instance of this class is created for each service instance by the Service Fabric runtime.
///
internal sealed class UdpService : StatelessService
{
private UdpCommunicationListener listener;
public UdpService(StatelessServiceContext context)
: base(context)
{ }
protected override IEnumerable CreateServiceInstanceListeners()
{
yield return new ServiceInstanceListener(initParams =>
{
this.listener = new UdpCommunicationListener();
this.listener.Initialize(initParams.CodePackageActivationContext);
return this.listener;
});
}
}
}
UdpCommunicationListener
using System;
using System.Diagnostics;
using System.Fabric;
using System.Fabric.Description;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
namespace UdpService
{
public class UdpCommunicationListener : ICommunicationListener, IDisposable
{
private readonly CancellationTokenSource processRequestsCancellation = new CancellationTokenSource();
public int Port { get; set; }
private UdpClient server;
///
/// Stops the Server Ungracefully
///
public void Abort()
{
this.StopWebServer();
}
///
/// Stops the Server Gracefully
///
/// Cancellation Token
/// Task for Asynchron usage
public Task CloseAsync(CancellationToken cancellationToken)
{
this.StopWebServer();
return Task.FromResult(true);
}
///
/// Free Resources
///
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Initializes Configuration
///
/// Code Package Activation Context
public void Initialize(ICodePackageActivationContext context)
{
EndpointResourceDescription serviceEndpoint = context.GetEndpoint("ServiceEndpoint");
this.Port = serviceEndpoint.Port;
}
///
/// Starts the Server
///
/// Cancellation Token
/// Task for Asynchron usage
public Task OpenAsync(CancellationToken cancellationToken)
{
try
{
this.server = new UdpClient(this.Port);
}
catch (Exception ex)
{
}
ThreadPool.QueueUserWorkItem((state) =>
{
this.MessageHandling(this.processRequestsCancellation.Token);
});
return Task.FromResult("udp://" + FabricRuntime.GetNodeContext().IPAddressOrFQDN + ":" + this.Port);
}
protected void MessageHandling(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, this.Port);
byte[] receivedBytes = this.server.Receive(ref ipEndPoint);
this.server.Send(receivedBytes, receivedBytes.Length, ipEndPoint);
Debug.WriteLine("Received bytes: " + receivedBytes.Length.ToString());
}
}
///
/// Receives the specified endpoint.
///
/// The endpoint.
///
public Task Receive(ref IPEndPoint endpoint)
{
return Task.FromResult(this.server.Receive(ref endpoint));
}
///
/// Free Resources and Stop Server
///
/// Disposing .NET Resources?
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (this.server != null)
{
try
{
this.server.Close();
this.server = null;
}
catch (Exception ex)
{
ServiceEventSource.Current.Message(ex.Message);
}
}
}
}
///
/// Stops Server and Free Handles
///
private void StopWebServer()
{
this.processRequestsCancellation.Cancel();
this.Dispose();
}
}
}
Last but not least the ServiceManifest.xml
UdpService.exe