public static void Main() { const string channel = "aeron:ipc"; const int streamId = 42; var buffer = new UnsafeBuffer(new byte[256]); var handler = HandlerHelper.ToFragmentHandler(PrintMessage); try { using (var aeron = Aeron.Connect()) using (var publisher = aeron.AddPublication(channel, streamId)) using (var subscriber = aeron.AddSubscription(channel, streamId)) { var message = buffer.PutStringWithoutLengthUtf8(0, "Hello World!"); publisher.Offer(buffer, 0, message); Console.WriteLine("Message sent..."); while (subscriber.Poll(handler, 1) == 0) { Thread.Sleep(10); } } } catch (Exception ex) { Console.WriteLine(ex); } finally { Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } }
public int Poll(FragmentHandler fragmentHandler, int fragmentLimit) #endif { var handler = HandlerHelper.ToFragmentHandler(fragmentHandler); return(Poll(handler, fragmentLimit)); }
public static void Main() { var ctx = new Aeron.Context() .AvailableImageHandler(SamplesUtil.PrintAvailableImage) .UnavailableImageHandler(SamplesUtil.PrintUnavailableImage); IIdleStrategy idleStrategy = new BusySpinIdleStrategy(); Console.WriteLine("Subscribing Ping at " + PingChannel + " on stream Id " + PingStreamID); Console.WriteLine("Publishing Pong at " + PongChannel + " on stream Id " + PongStreamID); var running = new AtomicBoolean(true); Console.CancelKeyPress += (_, e) => running.Set(false); using (var aeron = Aeron.Connect(ctx)) using (var pongPublication = aeron.AddPublication(PongChannel, PongStreamID)) using (var pingSubscription = aeron.AddSubscription(PingChannel, PingStreamID)) { var dataHandler = HandlerHelper.ToFragmentHandler( (buffer, offset, length, header) => PingHandler(pongPublication, buffer, offset, length) ); while (running) { idleStrategy.Idle(pingSubscription.Poll(dataHandler, FrameCountLimit)); } Console.WriteLine("Shutting down..."); } }
public AeronSubscription(Subscription subscription) { _subscription = subscription; // dataHandler method is called for every new datagram received _fragmentReassembler = new FragmentAssembler(HandlerHelper.ToFragmentHandler(CompleteMessageReceived)); }
public static async Task Main(string[] args) { var listenPort = ushort.Parse(args[0]); var servicePort = ushort.Parse(args[1]); var seeds = args.Skip(2).Select(Utils.IPEndPointFromString).ToArray(); var logger = Utils.CreateLogger <Program>(); var gossiper = await StartGossiper(listenPort, servicePort, seeds, logger); const int fragmentLimitCount = 10; string channel = "aeron:udp?endpoint=localhost:" + servicePort; // A unique identifier for a stream within a channel. Stream ID 0 is reserved // for internal use and should not be used by applications. const int streamId = 10; Console.WriteLine("Subscribing to " + channel + " on stream Id " + streamId); // dataHandler method is called for every new datagram received var fragmentHandler = HandlerHelper.ToFragmentHandler((buffer, offset, length, header) => { var data = new byte[length]; buffer.GetBytes(offset, data); Console.WriteLine($"Received message ({Encoding.UTF8.GetString(data)}) to stream {streamId:D} from session {header.SessionId:x} term id {header.TermId:x} term offset {header.TermOffset:D} ({length:D}@{offset:D})"); }); // Create a context, needed for client connection to media driver // A separate media driver process need to run prior to running this application var ctx = new Aeron.Context(); // Create an Aeron instance with client-provided context configuration, connect to the // media driver, and add a subscription for the given channel and stream using the supplied // dataHandler method, which will be called with new messages as they are received. // The Aeron and Subscription classes implement AutoCloseable, and will automatically // clean up resources when this try block is finished. using (var aeron = Aeron.Connect(ctx)) using (var subscription = aeron.AddSubscription(channel, streamId)) { IIdleStrategy idleStrategy = new BusySpinIdleStrategy(); // Try to read the data from subscriber while (true) { // poll delivers messages to the dataHandler as they arrive // and returns number of fragments read, or 0 // if no data is available. var fragmentsRead = subscription.Poll(fragmentHandler, fragmentLimitCount); // Give the IdleStrategy a chance to spin/yield/sleep to reduce CPU // use if no messages were received. idleStrategy.Idle(fragmentsRead); } } }
/// <summary> /// Return a reusable, parameterized <seealso cref="IFragmentHandler"/> that prints to stdout /// </summary> /// <param name="streamId"> to show when printing </param> /// <returns> subscription data handler function that prints the message contents </returns> public static IFragmentHandler PrintStringMessage(int streamId) { return(HandlerHelper.ToFragmentHandler((buffer, offset, length, header) => { var data = new byte[length]; buffer.GetBytes(offset, data); Console.WriteLine($"Message to stream {streamId:D} from session {header.SessionId:D} ({length:D}@{offset:D}) <<{Encoding.UTF8.GetString(data)}>>"); })); }
private void PollThread() { var idleStrategy = _config.ClientIdleStrategy.GetClientIdleStrategy(); var fragmentHandler = new FragmentAssembler(HandlerHelper.ToFragmentHandler(SubscriptionHandler)); while (_isRunning && !_isTerminating) { idleStrategy.Idle(_subscription.Poll(fragmentHandler, _frameCountLimit)); } }
public AeronClientSession(AeronClient client, string serverChannel, Publication publication, Subscription subscription, Action onConnected, Action onDisconnected, AeronClientMessageReceivedHandler onMessageReceived) { _client = client; _serverChannel = serverChannel; _publication = publication; _buffer = new UnsafeBuffer(); Subscription = subscription; OnDisconnected = onDisconnected; _onMessageReceived = onMessageReceived; _onConnected = onConnected; _isConnected = false; _fragmentAssembler = new FragmentAssembler(HandlerHelper.ToFragmentHandler(SubscriptionHandler)); }
public static void Main() { var ctx = new Aeron.Context() .AvailableImageHandler(AvailablePongImageHandler); var fragmentAssembler = new FragmentAssembler(HandlerHelper.ToFragmentHandler(PongHandler)); Console.WriteLine("Publishing Ping at " + PingChannel + " on stream Id " + PingStreamID); Console.WriteLine("Subscribing Pong at " + PongChannel + " on stream Id " + PongStreamID); Console.WriteLine("Message length of " + MessageLength + " bytes"); using (var aeron = Aeron.Connect(ctx)) { Console.WriteLine("Warming up... " + WarmupNumberOfIterations + " iterations of " + WarmupNumberOfMessages + " messages"); using (var publication = aeron.AddPublication(PingChannel, PingStreamID)) using (var subscription = aeron.AddSubscription(PongChannel, PongStreamID)) using (var byteBuffer = BufferUtil.AllocateDirectAligned(MessageLength, BitUtil.CACHE_LINE_LENGTH)) using (var atomicBuffer = new UnsafeBuffer(byteBuffer)) { Latch.Wait(); for (var i = 0; i < WarmupNumberOfIterations; i++) { RoundTripMessages(atomicBuffer, fragmentAssembler, publication, subscription, WarmupNumberOfMessages); } Thread.Sleep(100); do { Histogram.Reset(); Console.WriteLine("Pinging " + NumberOfMessages + " messages"); RoundTripMessages(atomicBuffer, fragmentAssembler, publication, subscription, NumberOfMessages); Console.WriteLine("Histogram of RTT latencies in microseconds."); Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: 1000); } while (Console.Read() == 'y'); } } }
/// <summary> /// Poll for new messages in a stream. If new messages are found beyond the last consumed position then they /// will be delivered to the <seealso cref="FragmentHandler"/> up to a limited number of fragments as specified or /// the maximum position specified. /// <para> /// Use a <seealso cref="FragmentAssembler"/> to assemble messages which span multiple fragments. /// /// </para> /// </summary> /// <param name="handler"> to which message fragments are delivered. </param> /// <param name="limitPosition"> to consume messages up to. </param> /// <param name="fragmentLimit"> for the number of fragments to be consumed during one polling operation. </param> /// <returns> the number of fragments that have been consumed. </returns> /// <seealso cref="FragmentAssembler" /> /// <seealso cref="ImageFragmentAssembler" /> public int BoundedPoll(FragmentHandler handler, long limitPosition, int fragmentLimit) { var fragmentHandler = HandlerHelper.ToFragmentHandler(handler); return(BoundedPoll(fragmentHandler, limitPosition, fragmentLimit)); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public ImageFragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = BufferBuilder.MIN_ALLOCATED_CAPACITY) { _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); _builder = new BufferBuilder(initialBufferLength); }
/// <summary> /// Return a reusable, parameteried <seealso cref="IFragmentHandler"/> that calls into a /// <seealso cref="RateReporter"/>. /// </summary> /// <param name="reporter"> for the rate </param> /// <returns> <seealso cref="IFragmentHandler"/> that records the rate information </returns> public static IFragmentHandler RateReporterHandler(RateReporter reporter) { return(HandlerHelper.ToFragmentHandler((buffer, offset, length, header) => reporter.OnMessage(1, length))); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public FragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = 0) { _initialBufferLength = initialBufferLength; _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public ImageFragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = 0) { _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); _builder = new BufferBuilder(initialBufferLength); }
public static void Main() { // Maximum number of message fragments to receive during a single 'poll' operation const int fragmentLimitCount = 10; // The channel (an endpoint identifier) to receive messages from const string channel = "aeron:udp?endpoint=localhost:40123"; // A unique identifier for a stream within a channel. Stream ID 0 is reserved // for internal use and should not be used by applications. const int streamId = 10; Console.WriteLine("Subscribing to " + channel + " on stream Id " + streamId); var running = new AtomicBoolean(true); // Register a SIGINT handler for graceful shutdown. Console.CancelKeyPress += (s, e) => running.Set(false); // dataHandler method is called for every new datagram received var fragmentHandler = HandlerHelper.ToFragmentHandler((buffer, offset, length, header) => { var data = new byte[length]; buffer.GetBytes(offset, data); Console.WriteLine($"Received message ({Encoding.UTF8.GetString(data)}) to stream {streamId:D} from session {header.SessionId:x} term id {header.TermId:x} term offset {header.TermOffset:D} ({length:D}@{offset:D})"); // Received the intended message, time to exit the program running.Set(false); }); // Create a context, needed for client connection to media driver // A separate media driver process need to run prior to running this application var ctx = new Aeron.Context(); // Create an Aeron instance with client-provided context configuration, connect to the // media driver, and add a subscription for the given channel and stream using the supplied // dataHandler method, which will be called with new messages as they are received. // The Aeron and Subscription classes implement AutoCloseable, and will automatically // clean up resources when this try block is finished. using (var aeron = Aeron.Connect(ctx)) using (var subscription = aeron.AddSubscription(channel, streamId)) { IIdleStrategy idleStrategy = new BusySpinIdleStrategy(); // Try to read the data from subscriber while (running) { // poll delivers messages to the dataHandler as they arrive // and returns number of fragments read, or 0 // if no data is available. var fragmentsRead = subscription.Poll(fragmentHandler, fragmentLimitCount); // Give the IdleStrategy a chance to spin/yield/sleep to reduce CPU // use if no messages were received. idleStrategy.Idle(fragmentsRead); } Console.WriteLine("Press any key..."); Console.ReadLine(); } }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public FragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = BufferBuilder.MIN_ALLOCATED_CAPACITY) { _initialBufferLength = initialBufferLength; _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); }