static void Main(string[] args) { Console.WriteLine($"Connecting to Redis at {REDIS_URL}"); try { redis = ConnectionMultiplexer.Connect(REDIS_URL); db = redis.GetDatabase(); } catch (Exception ex) { Console.WriteLine("Failed to start redis: {0}", ex); redis?.Close(); Environment.Exit(1); } try { var opts = new ServiceRegistrationOptions { sender_localpart = "mc", as_token = "foobar", hs_token = "foobar", id = "matrix-cached", url = "http://*****:*****@_xmpp_.*", }); var reg = new ServiceRegistration(opts); appservice = new MatrixAppservice(reg, "localhost", "http://localhost:8008"); appservice.OnEvent += AppserviceOnOnEvent; Thread t = new Thread(listenForRequests); t.Start(); appservice.Run(); t.Join(); } catch (Exception ex) { Console.WriteLine("Failed to start appservice: {0}", ex); redis.Close(); Environment.Exit(1); } }
/// <summary> /// Requests a service name to be assigned to the connection. /// </summary> /// <param name="serviceName">Name of the service.</param> /// <param name="options"></param> /// <exception cref="ObjectDisposedException">The connection has been disposed.</exception> /// <exception cref="InvalidOperationException">The operation is invalid in the current state.</exception> /// <exception cref="DisconnectedException">The connection was closed after it was established.</exception> /// <exception cref="DBusException">Error returned by remote peer.</exception> /// <remarks> /// This operation is not supported for AutoConnection connections. /// </remarks> public Task RegisterServiceAsync(string serviceName, ServiceRegistrationOptions options) => RegisterServiceAsync(serviceName, null, options);
/// <summary> /// Requests a service name to be assigned to the connection. /// </summary> /// <param name="serviceName">Name of the service.</param> /// <param name="onLost">Action invoked when the service name is no longer assigned to the connection.</param> /// <param name="options"></param> /// <exception cref="ObjectDisposedException">The connection has been disposed.</exception> /// <exception cref="InvalidOperationException">The operation is invalid in the current state.</exception> /// <exception cref="DisconnectedException">The connection was closed after it was established.</exception> /// <exception cref="DBusException">Error returned by remote peer.</exception> /// <remarks> /// This operation is not supported for AutoConnection connections. /// </remarks> public async Task RegisterServiceAsync(string serviceName, Action onLost = null, ServiceRegistrationOptions options = ServiceRegistrationOptions.Default) { CheckNotConnectionType(ConnectionType.ClientAutoConnect); var connection = GetConnectedConnection(); if (!options.HasFlag(ServiceRegistrationOptions.AllowReplacement) && (onLost != null)) { throw new ArgumentException($"{nameof(onLost)} can only be set when {nameof(ServiceRegistrationOptions.AllowReplacement)} is also set", nameof(onLost)); } RequestNameOptions requestOptions = RequestNameOptions.DoNotQueue; if (options.HasFlag(ServiceRegistrationOptions.ReplaceExisting)) { requestOptions |= RequestNameOptions.ReplaceExisting; } if (options.HasFlag(ServiceRegistrationOptions.AllowReplacement)) { requestOptions |= RequestNameOptions.AllowReplacement; } var reply = await connection.RequestNameAsync(serviceName, requestOptions, null, onLost, CaptureSynchronizationContext()); switch (reply) { case RequestNameReply.PrimaryOwner: return; case RequestNameReply.Exists: throw new InvalidOperationException("Service is registered by another connection"); case RequestNameReply.AlreadyOwner: throw new InvalidOperationException("Service is already registered by this connection"); case RequestNameReply.InQueue: default: throw new ProtocolException("Unexpected reply"); } }
/// <summary> /// Queues a service name registration for the connection. /// </summary> /// <param name="serviceName">Name of the service.</param> /// <param name="options">Options for the registration.</param> /// <exception cref="ObjectDisposedException">The connection has been disposed.</exception> /// <exception cref="InvalidOperationException">The operation is invalid in the current state.</exception> /// <exception cref="DisconnectedException">The connection was closed after it was established.</exception> /// <exception cref="DBusException">Error returned by remote peer.</exception> /// <exception cref="ProtocolException">Unexpected reply.</exception> /// <remarks> /// This operation is not supported for AutoConnection connections. /// </remarks> public Task QueueServiceRegistrationAsync(string serviceName, ServiceRegistrationOptions options) => QueueServiceRegistrationAsync(serviceName, null, null, options);
public void Run(String[] args) { if (!ParseCommandLine(args)) { return; } SessionOptions.ServerAddress[] servers = new SessionOptions.ServerAddress[d_hosts.Count]; for (int i = 0; i < d_hosts.Count; ++i) { servers[i] = new SessionOptions.ServerAddress(d_hosts[i], d_port); } SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerAddresses = servers; sessionOptions.AuthenticationOptions = d_authOptions; sessionOptions.AutoRestartOnDisconnection = true; sessionOptions.NumStartAttempts = servers.Length; System.Console.Write("Connecting to"); foreach (SessionOptions.ServerAddress server in sessionOptions.ServerAddresses) { System.Console.Write(" " + server); } System.Console.WriteLine(); ProviderSession session = new ProviderSession(sessionOptions, ProcessEvent); if (!session.Start()) { System.Console.Error.WriteLine("Failed to start session"); return; } Identity identity = null; if (d_authOptions != null) { if (!Authorize(out identity, session)) { return; } } if (d_groupId != null) { // NOTE: will perform explicit service registration here, instead of letting // createTopics do it, as the latter approach doesn't allow for custom // ServiceRegistrationOptions ServiceRegistrationOptions serviceRegistrationOptions = new ServiceRegistrationOptions(); serviceRegistrationOptions.GroupId = d_groupId; serviceRegistrationOptions.ServicePriority = d_priority; if (!session.RegisterService(d_service, identity, serviceRegistrationOptions)) { System.Console.Write("Failed to register " + d_service); return; } } TopicList topicList = new TopicList(); for (int i = 0; i < d_topics.Count; i++) { topicList.Add( d_service + "/" + d_topics[i], new CorrelationID(new MyStream(d_topics[i]))); } session.CreateTopics( topicList, ResolveMode.AUTO_REGISTER_SERVICES, identity); // createTopics() is synchronous, topicList will be updated // with the results of topic creation (resolution will happen // under the covers) List <MyStream> myStreams = new List <MyStream>(); for (int i = 0; i < topicList.Size; ++i) { MyStream stream = (MyStream)topicList.CorrelationIdAt(i).Object; if (topicList.StatusAt(i) == TopicList.TopicStatus.CREATED) { Message msg = topicList.MessageAt(i); stream.setTopic(session.GetTopic(msg)); myStreams.Add(stream); System.Console.WriteLine("Topic created: " + topicList.TopicStringAt(i)); } else { System.Console.WriteLine("Stream '" + stream.getId() + "': topic not resolved, status = " + topicList.StatusAt(i)); } } Service service = session.GetService(d_service); // Now we will start publishing Name eventName = Name.GetName("MarketDataEvents"); Name high = Name.GetName("HIGH"); Name low = Name.GetName("LOW"); long tickCount = 1; for (int eventCount = 0; eventCount < d_maxEvents; ++eventCount) { Event eventObj = service.CreatePublishEvent(); EventFormatter eventFormatter = new EventFormatter(eventObj); for (int index = 0; index < myStreams.Count; index++) { Topic topic = myStreams[index].getTopic(); if (!topic.IsActive()) { continue; } eventFormatter.AppendMessage(eventName, topic); if (1 == tickCount) { eventFormatter.SetElement("OPEN", 1.0); } else if (2 == tickCount) { eventFormatter.SetElement("BEST_BID", 3.0); } eventFormatter.SetElement(high, tickCount * 1.0); eventFormatter.SetElement(low, tickCount * 0.5); ++tickCount; } foreach (Message msg in eventObj) { System.Console.WriteLine(msg); } session.Publish(eventObj); Thread.Sleep(2 * 1000); } session.Stop(); }
public void Run(string[] args) //throws Exception { if (!ParseCommandLine(args)) { return; } SessionOptions.ServerAddress[] servers = new SessionOptions.ServerAddress[d_hosts.Count]; for (int i = 0; i < d_hosts.Count; ++i) { servers[i] = new SessionOptions.ServerAddress(d_hosts[i], d_port); } SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerAddresses = servers; sessionOptions.AuthenticationOptions = d_authOptions; sessionOptions.AutoRestartOnDisconnection = true; sessionOptions.NumStartAttempts = servers.Length; Console.Write("Connecting to"); foreach (SessionOptions.ServerAddress server in sessionOptions.ServerAddresses) { Console.Write(" " + server); } Console.WriteLine(); ProviderSession session = new ProviderSession( sessionOptions, processEvent); if (!session.Start()) { Console.Error.WriteLine("Failed to start session"); return; } Identity identity = null; if (d_authOptions != null) { bool isAuthorized = false; identity = session.CreateIdentity(); if (session.OpenService("//blp/apiauth")) { Service authService = session.GetService("//blp/apiauth"); if (Authorize(authService, identity, session, new CorrelationID())) { isAuthorized = true; } } if (!isAuthorized) { System.Console.Error.WriteLine("No authorization"); return; } } ServiceRegistrationOptions serviceRegistrationOptions = new ServiceRegistrationOptions(); serviceRegistrationOptions.GroupId = d_groupId; serviceRegistrationOptions.ServicePriority = d_priority; if (!session.RegisterService(d_service, identity, serviceRegistrationOptions)) { Console.WriteLine("Failed to register " + d_service); return; } Console.WriteLine("Service registered " + d_service); //Publishing events for the active topics of the designated service. PublishEvents(session); session.Stop(); }
/// <summary> /// Queues a service name registration for the connection. /// </summary> /// <param name="serviceName">Name of the service.</param> /// <param name="onAquired">Action invoked when the service name is assigned to the connection.</param> /// <param name="onLost">Action invoked when the service name is no longer assigned to the connection.</param> /// <param name="options">Options for the registration.</param> /// <exception cref="ObjectDisposedException">The connection has been disposed.</exception> /// <exception cref="InvalidOperationException">The operation is invalid in the current state.</exception> /// <exception cref="DisconnectedException">The connection was closed after it was established.</exception> /// <exception cref="DBusException">Error returned by remote peer.</exception> /// <exception cref="ProtocolException">Unexpected reply.</exception> /// <remarks> /// This operation is not supported for AutoConnection connections. /// </remarks> public async Task QueueServiceRegistrationAsync(string serviceName, Action onAquired = null, Action onLost = null, ServiceRegistrationOptions options = ServiceRegistrationOptions.Default) { CheckNotConnectionType(ConnectionType.ClientAutoConnect); var connection = GetConnectedConnection(); if (!options.HasFlag(ServiceRegistrationOptions.AllowReplacement) && (onLost != null)) { throw new ArgumentException($"{nameof(onLost)} can only be set when {nameof(ServiceRegistrationOptions.AllowReplacement)} is also set", nameof(onLost)); } RequestNameOptions requestOptions = RequestNameOptions.None; if (options.HasFlag(ServiceRegistrationOptions.ReplaceExisting)) { requestOptions |= RequestNameOptions.ReplaceExisting; } if (options.HasFlag(ServiceRegistrationOptions.AllowReplacement)) { requestOptions |= RequestNameOptions.AllowReplacement; } var reply = await connection.RequestNameAsync(serviceName, requestOptions, onAquired, onLost, CaptureSynchronizationContext()).ConfigureAwait(false); switch (reply) { case RequestNameReply.PrimaryOwner: case RequestNameReply.InQueue: return; case RequestNameReply.Exists: case RequestNameReply.AlreadyOwner: default: throw new ProtocolException("Unexpected reply"); } }
public static async Task <RequestNameReply> RegisterServiceCallback(this IConnection connection, string serviceName, ServiceRegistrationOptions options = ServiceRegistrationOptions.Default, Action <string> onAquired = null, Action <string> onLost = null) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (string.IsNullOrEmpty(serviceName)) { throw new ArgumentNullException(nameof(serviceName)); } IDisposable acquireDisposer = null; if (onAquired != null) { acquireDisposer = await connection.DBus.WatchNameAcquired(name => { if (name == serviceName) { onAquired(name); var c = acquireDisposer; if (c != null) { c.Dispose(); } } }); } IDisposable lostDisposer = null; if (onLost != null) { lostDisposer = await connection.DBus.WatchNameLost(name => { if (name == serviceName) { onLost(name); var c = lostDisposer; if (c != null) { c.Dispose(); } } }); } var requestOptions = RequestNameOptions.None; if (options.HasFlag(ServiceRegistrationOptions.ReplaceExisting)) { requestOptions |= RequestNameOptions.ReplaceExisting; } if (options.HasFlag(ServiceRegistrationOptions.AllowReplacement)) { requestOptions |= RequestNameOptions.AllowReplacement; } try { return(await connection.DBus.RequestName(serviceName, requestOptions)); } catch (Exception) { if (acquireDisposer != null) { acquireDisposer.Dispose(); } if (lostDisposer != null) { lostDisposer.Dispose(); } throw; } }
/// <summary> /// Register service name and wait (Task) until name acquired. /// </summary> /// <param name="connection"></param> /// <param name="serviceName"></param> /// <param name="options"></param> /// <param name="cancellationToken"></param> /// <param name="onLost"></param> /// <returns></returns> public static async Task RegisterServiceWait(this IConnection connection, string serviceName, ServiceRegistrationOptions options = ServiceRegistrationOptions.Default, Action <string> onLost = null, CancellationToken cancellationToken = default(CancellationToken)) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (string.IsNullOrEmpty(serviceName)) { throw new ArgumentNullException(nameof(serviceName)); } var tcs = new TaskCompletionSource <bool>(); IDisposable acquireDisposer = null; acquireDisposer = await connection.DBus.WatchNameAcquired(name => { if (name == serviceName) { tcs.TrySetResult(true); var c = acquireDisposer; if (c != null) { c.Dispose(); } } }); IDisposable lostDisposer = null; if (onLost != null) { lostDisposer = await connection.DBus.WatchNameLost(name => { if (name == serviceName) { onLost(name); var c = lostDisposer; if (c != null) { c.Dispose(); } tcs.TrySetResult(false); } }); } var requestOptions = RequestNameOptions.None; if (options.HasFlag(ServiceRegistrationOptions.ReplaceExisting)) { requestOptions |= RequestNameOptions.ReplaceExisting; } if (options.HasFlag(ServiceRegistrationOptions.AllowReplacement)) { requestOptions |= RequestNameOptions.AllowReplacement; } RequestNameReply reply; try { reply = await connection.DBus.RequestName(serviceName, requestOptions); } catch (Exception) { if (acquireDisposer != null) { acquireDisposer.Dispose(); } if (lostDisposer != null) { lostDisposer.Dispose(); } throw; } switch (reply) { case RequestNameReply.AlreadyOwner: case RequestNameReply.PrimaryOwner: return; case RequestNameReply.Exists: case RequestNameReply.InQueue: if (cancellationToken.CanBeCanceled) { cancellationToken.Register(() => tcs.TrySetCanceled()); } if (await tcs.Task) { return; } throw new InvalidOperationException("Name could not be acquired"); } }
public void Run(String[] args) { if (!ParseCommandLine(args)) { return; } SessionOptions.ServerAddress[] servers = new SessionOptions.ServerAddress[d_hosts.Count]; for (int i = 0; i < d_hosts.Count; ++i) { servers[i] = new SessionOptions.ServerAddress(d_hosts[i], d_port); } SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerAddresses = servers; sessionOptions.AuthenticationOptions = d_authOptions; sessionOptions.AutoRestartOnDisconnection = true; sessionOptions.NumStartAttempts = servers.Length; Console.Write("Connecting to"); foreach (SessionOptions.ServerAddress server in sessionOptions.ServerAddresses) { Console.Write(" " + server); } Console.WriteLine(); ProviderSession session = new ProviderSession(sessionOptions, ProcessEvent); if (!session.Start()) { Console.Error.WriteLine("Failed to start session"); return; } Identity identity = null; if (d_authOptions != null) { bool isAuthorized = false; identity = session.CreateIdentity(); if (session.OpenService("//blp/apiauth")) { Service authService = session.GetService("//blp/apiauth"); if (Authorize(authService, identity, session, new CorrelationID())) { isAuthorized = true; } } if (!isAuthorized) { System.Console.Error.WriteLine("No authorization"); return; } } ServiceRegistrationOptions serviceRegistrationOptions = new ServiceRegistrationOptions(); serviceRegistrationOptions.GroupId = d_groupId; serviceRegistrationOptions.ServicePriority = d_priority; if (d_useSsc) { Console.WriteLine( String.Format( "Activating sub service code range [{0}, {1}] " + "@ priority: {2}", d_sscBegin, d_sscEnd, d_sscPriority)); try { serviceRegistrationOptions.AddActiveSubServiceCodeRange( d_sscBegin, d_sscEnd, d_sscPriority); } catch (Exception e) { Console.WriteLine( "FAILED to add active sub service codes. Exception " + e); } } bool wantAsyncRegisterService = true; if (wantAsyncRegisterService) { Object registerServiceResponseMonitor = new Object(); CorrelationID registerCID = new CorrelationID(registerServiceResponseMonitor); lock (registerServiceResponseMonitor) { if (d_verbose > 0) { Console.WriteLine("start registerServiceAsync, cid = " + registerCID); } session.RegisterServiceAsync( d_service, identity, registerCID, serviceRegistrationOptions); for (int i = 0; d_registerServiceResponse == null && i < 10; ++i) { Monitor.Wait(registerServiceResponseMonitor, 1000); } } } else { bool result = session.RegisterService( d_service, identity, serviceRegistrationOptions); d_registerServiceResponse = result; } Service service = session.GetService(d_service); if (service != null && d_registerServiceResponse == true) { Console.WriteLine("Service registered: " + d_service); } else { Console.Error.WriteLine("Service registration failed: " + d_service); return; } // Dump schema for the service if (d_verbose > 1) { Console.WriteLine("Schema for service:" + d_service); for (int i = 0; i < service.NumEventDefinitions; ++i) { SchemaElementDefinition eventDefinition = service.GetEventDefinition(i); Console.WriteLine(eventDefinition); } } // Now we will start publishing int eventCount = 0; long tickCount = 1; while (d_running) { Event eventObj; lock (d_topicSet) { if (d_topicSet.Count == 0) { Monitor.Wait(d_topicSet, 100); } if (d_topicSet.Count == 0) { continue; } eventObj = service.CreatePublishEvent(); EventFormatter eventFormatter = new EventFormatter(eventObj); bool publishNull = false; if (d_clearInterval > 0 && eventCount == d_clearInterval) { eventCount = 0; publishNull = true; } foreach (Topic topic in d_topicSet.Keys) { if (!topic.IsActive()) { System.Console.WriteLine("[WARNING] Publishing on an inactive topic."); } eventFormatter.AppendMessage("MarketDataEvents", topic); if (publishNull) { eventFormatter.SetElementNull("HIGH"); eventFormatter.SetElementNull("LOW"); } else { ++eventCount; if (1 == tickCount) { eventFormatter.SetElement("BEST_ASK", 100.0); } else if (2 == tickCount) { eventFormatter.SetElement("BEST_BID", 99.0); } eventFormatter.SetElement("HIGH", 100 + tickCount * 0.01); eventFormatter.SetElement("LOW", 100 - tickCount * 0.005); ++tickCount; } } } foreach (Message msg in eventObj) { Console.WriteLine(msg); } session.Publish(eventObj); Thread.Sleep(10 * 1000); if (tickCount % 3 == 0) { Deactivate(session); Thread.Sleep(10 * 1000); Activate(session); } } session.Stop(); }
public void Run(String[] args) { if (!ParseCommandLine(args)) { return; } SessionOptions.ServerAddress[] servers = new SessionOptions.ServerAddress[d_hosts.Count]; for (int i = 0; i < d_hosts.Count; ++i) { servers[i] = new SessionOptions.ServerAddress(d_hosts[i], d_port); } SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerAddresses = servers; sessionOptions.AuthenticationOptions = d_authOptions; sessionOptions.AutoRestartOnDisconnection = true; sessionOptions.NumStartAttempts = servers.Length; System.Console.Write("Connecting to"); foreach (SessionOptions.ServerAddress server in sessionOptions.ServerAddresses) { System.Console.Write(" " + server); } System.Console.WriteLine(); ProviderSession session = new ProviderSession(sessionOptions, ProcessEvent); if (!session.Start()) { System.Console.Error.WriteLine("Failed to start session"); return; } Identity identity = null; if (d_authOptions.Length != 0) { Object tokenResponseMonitor = new Object(); lock (tokenResponseMonitor) { session.GenerateToken(new CorrelationID(tokenResponseMonitor)); long waitTime = 10 * 1000; long tokenResponseTimeout = System.DateTime.Now.Ticks / 10000 + waitTime; while (d_tokenGenerationResponse == null && waitTime > 0) { Monitor.Wait(tokenResponseMonitor, (int)waitTime); waitTime = tokenResponseTimeout - System.DateTime.Now.Ticks / 10000; } if (d_tokenGenerationResponse == null) { System.Console.Error.WriteLine("Timeout waiting for token"); System.Environment.Exit(1); } else if (d_tokenGenerationResponse == false || d_token == null) { System.Console.Error.WriteLine("Token generation failed"); System.Environment.Exit(1); } } Object authorizationResponseMonitor = new Object(); if (session.OpenService("//blp/apiauth")) { Service authService = session.GetService("//blp/apiauth"); Request authRequest = authService.CreateAuthorizationRequest(); authRequest.Set("token", d_token); identity = session.CreateIdentity(); d_authorizationResponseCorrelationId = new CorrelationID(authorizationResponseMonitor); lock (authorizationResponseMonitor) { session.SendAuthorizationRequest( authRequest, identity, d_authorizationResponseCorrelationId); long waitTime = 60 * 1000; long authorizationResponseTimeout = System.DateTime.Now.Ticks / 10000 + waitTime; while (d_authorizationResponse == null && waitTime > 0) { Monitor.Wait(authorizationResponseMonitor, 1000); waitTime = authorizationResponseTimeout - System.DateTime.Now.Ticks / 10000; } if (d_authorizationResponse == null) { System.Console.Error.WriteLine("Timeout waiting for authorization"); System.Environment.Exit(1); } else if (d_authorizationResponse == false) { System.Console.Error.WriteLine("Authorization failed"); System.Environment.Exit(1); } } } } ServiceRegistrationOptions serviceRegistrationOptions = new ServiceRegistrationOptions(); serviceRegistrationOptions.GroupId = d_groupId; serviceRegistrationOptions.ServicePriority = d_priority; bool wantAsyncRegisterService = true; if (wantAsyncRegisterService) { Object registerServiceResponseMonitor = new Object(); CorrelationID registerCID = new CorrelationID(registerServiceResponseMonitor); lock (registerServiceResponseMonitor) { if (d_verbose > 0) { System.Console.WriteLine("start registerServiceAsync, cid = " + registerCID); } session.RegisterServiceAsync(d_service, identity, registerCID, serviceRegistrationOptions); for (int i = 0; d_registerServiceResponse == null && i < 10; ++i) { Monitor.Wait(registerServiceResponseMonitor, 1000); } } } else { bool result = session.RegisterService(d_service, identity, serviceRegistrationOptions); d_registerServiceResponse = result; } Service service = session.GetService(d_service); if (service != null && d_registerServiceResponse == true) { System.Console.WriteLine("Service registered: " + d_service); } else { System.Console.Error.WriteLine("Service registration failed: " + d_service); System.Environment.Exit(1); } // Dump schema for the service if (d_verbose > 1) { System.Console.WriteLine("Schema for service:" + d_service); for (int i = 0; i < service.NumEventDefinitions; ++i) { SchemaElementDefinition eventDefinition = service.GetEventDefinition(i); System.Console.WriteLine(eventDefinition); } } // Now we will start publishing long tickCount = 1; while (g_running) { Event eventObj; lock (d_topicSet) { if (d_topicSet.Count == 0) { Monitor.Wait(d_topicSet, 100); } if (d_topicSet.Count == 0) { continue; } eventObj = service.CreatePublishEvent(); EventFormatter eventFormatter = new EventFormatter(eventObj); foreach (Topic topic in d_topicSet.Keys) { if (!topic.IsActive()) { continue; } eventFormatter.AppendMessage("MarketDataEvents", topic); if (1 == tickCount) { eventFormatter.SetElement("BEST_ASK", 100.0); } else if (2 == tickCount) { eventFormatter.SetElement("BEST_BID", 99.0); } eventFormatter.SetElement("HIGH", 100 + tickCount * 0.01); eventFormatter.SetElement("LOW", 100 - tickCount * 0.005); ++tickCount; } } foreach (Message msg in eventObj) { System.Console.WriteLine(msg); } session.Publish(eventObj); Thread.Sleep(10 * 1000); } session.Stop(); }