Пример #1
0
        /// <summary>
        /// Opens the websocket connection and sends the CONNECT message.
        /// </summary>
        /// <returns>&lt;System.Boolean&gt; true if successful.</returns>
        public async Task <bool> ConnectAsync(Action <string> errorsEventHandler)
        {
            const string WEBSOCKETPATH = "/w/messages/websocket";    // Based on https://docs.nem.io/en/nem-dev-basics-docker/blockchain-monitoring

            await ClientWs.ConnectAsync(new Uri(string.Concat("ws://", Domain, ":", Port, WEBSOCKETPATH)), CancellationToken.None);

            if (ClientWs.State != WebSocketState.Open)
            {
                return(false);
            }
            // Send CONNECT
            StompMessage connect = new StompMessage(StompMessage.ClientCommands.CONNECT);

            // Set message headers, might not be needed
            //connect["accept-version"] = "1.1,1.0";
            //connect["heart-beat"] = "10000, 10000";  // out, in
            await SendAsync(connect);

            // Read the answer from the server
            StompMessage connectedMsg = StompMessage.Deserialize(await ReadSocketAsync());

            if (connectedMsg.Command != StompMessage.ServerResponses.CONNECTED)
            {
                return(false);
            }
            // Subscribe to errors channel
            await SubscribeToErrorsAsync(errorsEventHandler);

            // Start the Loop to read answers
            Task loop = LoopReadStompMsgsAsync(); // Explicitely not using await, to allow the Loop to run asynchronously without waiting for it to complete!

            return(true);
        }
Пример #2
0
        /// <summary>
        /// Subscribes to the channel on the destination path.
        /// </summary>
        /// <param name="destinationPath">The channel.</param>
        async Task SendSubscribeStompMsgAsync(string destinationPath, Address destinationAddress = null)
        {
            StompMessage subscribe = new StompMessage(StompMessage.ClientCommands.SUBSCRIBE);

            subscribe.SetSubscriptionId(SubscriptionCounter++);
            subscribe.SetDestination(destinationPath, destinationAddress);
            await SendAsync(subscribe);  // The LoopReadStompMsgsAsync will process the answer from the server

            Debug.WriteLine("Subscription requested on path " + subscribe.GetDestination());
        }
Пример #3
0
        /// <summary>
        /// Subscribes to the channel for Definitions of Mosaics owned by the given Account. The Eventhandler will be invoked when a message is received on the channel.
        /// </summary>
        /// <param name="account"></param>
        /// <param name="mosaicDefinitionEventHandler"></param>
        /// <returns></returns>
        public async Task SubscribeToOwnedMosaicDefinitionsAsync(string account, Action <Address, MosaicInfo> mosaicDefinitionEventHandler)
        {
            Address destinationAddress = new Address(account);

            this.OnMosaicDefinitionEventHandler = mosaicDefinitionEventHandler;
            await SendSubscribeStompMsgAsync(ChannelPaths.OWNEDMOSAICDEFINITION, destinationAddress);

            // Send an explicit message to request an immediate answer on the channel
            StompMessage send = new StompMessage(StompMessage.ClientCommands.SEND, "{'account':'" + destinationAddress.Plain + "'}");

            send.SetDestination(ApiPaths.OWNEDMOSAICDEFINITIONS);
            await SendAsync(send);  // The LoopReadStompMsgsAsync will process the answer from the server
        }
Пример #4
0
        /// <summary>
        /// Subscribes to the channel for Mosaics owned by the given Account. The Eventhandler will be invoked when a message is received on the channel.
        /// </summary>
        /// <param name="account"></param>
        /// <param name="mosaicEventHandler"></param>
        public async Task SubscribeToOwnedMosaicsAsync(string account, Action <Address, MosaicAmount> mosaicEventHandler)
        {
            Address destinationAddress = new Address(account);

            this.OnMosaicEventHandler = mosaicEventHandler;   // The callback will be invoked for each msg received per Mosaic owned
            await SendSubscribeStompMsgAsync(ChannelPaths.OWNEDMOSAICS, destinationAddress);

            // Send an explicit message to request an immediate answer on the channel
            StompMessage send = new StompMessage(StompMessage.ClientCommands.SEND, "{'account':'" + destinationAddress.Plain + "'}");

            send.SetDestination(ApiPaths.OWNEDMOSAICS);
            await SendAsync(send);  // The LoopReadStompMsgsAsync will process the answer from the server
        }
Пример #5
0
        /// <summary>
        /// Subscribes to the channel for an Account. The Eventhandler will be invoked when a message is received on the channel.
        /// </summary>
        /// <param name="account"></param>
        /// <param name="accountEventHandler"></param>
        public async Task SubscribeToAccountAsync(string account, Action <AccountInfo> accountEventHandler)
        {
            Address destinationAddress = new Address(account);

            this.OnAccountEventHandler = accountEventHandler;
            await SendSubscribeStompMsgAsync(ChannelPaths.ACCOUNT, destinationAddress);

            // Send an explicit message to request an immediate answer on the channel
            StompMessage send = new StompMessage(StompMessage.ClientCommands.SEND, "{'account':'" + destinationAddress.Plain + "'}");

            send.SetDestination(ApiPaths.ACCOUNT);
            await SendAsync(send);  // The LoopReadStompMsgsAsync will process the answer from the server
        }
Пример #6
0
        /// <summary>
        /// Loop to read Stomp messages from the websocket and call appropriate actions.
        /// </summary>
        private async Task LoopReadStompMsgsAsync()
        {
            while (ClientWs.State == WebSocketState.Open)   // Infinite loop for as long as we are running with an open socket
            {
                var msg = await ReadSocketAsync();

                StompMessage stompMsg = StompMessage.Deserialize(msg);
                switch (stompMsg.Command)
                {
                case StompMessage.ServerResponses.ERROR:
                    this.OnErrorEventHandler?.Invoke(stompMsg.Body);
                    break;

                case StompMessage.ServerResponses.MESSAGE:
                    ProcessReceivedMessage(stompMsg.GetDestination(), stompMsg.Body);
                    break;

                default:
                    // throw exception?
                    Debug.WriteLine("Received STOMP Message with an unsupported Command: " + stompMsg);
                    break;
                }
            }
        }
Пример #7
0
 /// <summary>
 /// Sends the StompMessage Asynchronously. Call LoopReadStompMsgsAsync to process answers from the server.
 /// </summary>
 /// <param name="stompMsg"></param>
 async Task SendAsync(StompMessage stompMsg)
 {
     byte[] encoded = Encoding.UTF8.GetBytes(stompMsg.Serialize());
     ArraySegment <byte> segment = new ArraySegment <byte>(encoded, 0, encoded.Length);
     await ClientWs.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None);
 }