예제 #1
0
        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);
            }
        }
예제 #2
0
 /// <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);
예제 #3
0
        /// <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");
            }
        }
예제 #4
0
 /// <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();
        }
예제 #7
0
        /// <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");
            }
        }
예제 #10
0
        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();
        }
예제 #11
0
        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();
        }