Esempio n. 1
0
 /// <summary>
 ///     Add a new subscription to the given socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="subscription"></param>
 public void AddSubscription(IWebsocketConnection socket, Subscription subscription)
 {
     lock (_locker)
     {
         if (_allSockets.TryGetValue(socket, out var list))
         {
             list.Add(subscription);
         }
         else
         {
             _allSockets.Add(socket, new List <Subscription> {
                 subscription
             });
         }
     }
 }
Esempio n. 2
0
        /// <summary>
        ///     Broadcasts a decoded transaction to a given socket
        /// </summary>
        /// <param name="transaction">decoded transaction to broadcast</param>
        /// <param name="socket">socket to which to broadcast the transaction</param>
        private static void BroadcastTransaction(Transaction transaction, IWebsocketConnection socket)
        {
            try
            {
                var outputs = transaction.Outputs.Aggregate("", (current, output) => current + ("{ \"type\": \"" + output.Type + "\", \"address\": \"" + output.Address + "\", \"value\": \"" + output.Value + "\", \"script\": \"" + output.ScriptHex + "\" }, "));

                outputs = outputs.Substring(0, outputs.Length - 2);

                socket.Send("{ \"op\": \"new_tx\", \"txid\": \"" + transaction.TXIDHex + "\", " +
                            "\"inputs\": " + transaction.Inputs.Length + ", \"outputs\": [ " +
                            outputs + " ]");
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to broadcast. " + e.Message);
            }
        }
Esempio n. 3
0
        internal Client(OrtcClient ortcClient)
        {
            context = ortcClient;

            _gotOnOpenCount = 0;

            _permissions             = new List <KeyValuePair <string, string> >();
            _subscribedChannels      = new RealtimeDictionary <string, ChannelSubscription>();
            _multiPartMessagesBuffer = new RealtimeDictionary <string, RealtimeDictionary <int, BufferedMessage> >();

            _heartbeatTimer  = new Timer(_heartbeatTimer_Elapsed, context.HeartbeatTime * 1000);
            _connectionTimer = new Timer(_connectionTimer_Elapsed, Constants.SERVER_HB_COUNT * 1000);
            _reconnectTimer  = new Timer(_reconnectTimer_Elapsed, context.ConnectionTimeout * 1000);

            _balancer = DependencyService.Get <IBalancer> ();

            if (_balancer == null)
            {
                throw new OrtcGenericException(
                          "DependencyService Failed, please include the platform plugins. This may be caused linker stripping.");
            }

            _webSocketConnection = DependencyService.Get <IWebsocketConnection>();

            if (_webSocketConnection == null)
            {
                throw new OrtcGenericException(
                          "DependencyService Failed, please include the platform plugins. This may be caused linker stripping.");
            }

            _webSocketConnection.OnOpened          += _webSocketConnection_OnOpened;
            _webSocketConnection.OnClosed          += _webSocketConnection_OnClosed;
            _webSocketConnection.OnError           += _webSocketConnection_OnError;
            _webSocketConnection.OnMessageReceived += _webSocketConnection_OnMessageReceived;

            _msgProcessor = new MsgProcessor(this);
        }
Esempio n. 4
0
        /// <summary>
        ///     Handles json messages:
        ///         {"op": "block"}
        ///         {"op": "transaction"}
        ///         {"op": "address", "address": "[CASH_ADDRESS]"}
        ///         {"op": "opreturn", "prefix": "[PREFIX(HEX)]"}
        ///         {"op": "rm_block"}
        ///         {"op": "rm_transaction"}
        ///         {"op": "rm_address", "address": "[CASH_ADDRESS]"}
        ///         {"op": "rm_opreturn", "prefix": "[PREFIX(HEX)]"}
        ///     - Validates json
        ///     - Validates parameters
        ///     - Sends response (error or ok)
        ///     - Adds valid subscriptions to subscription handler
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="message"></param>
        /// <param name="subscriptionHandler"></param>
        public static void HandleMessage(IWebsocketConnection socket, string message, SubscriptionHandler subscriptionHandler)
        {
            message = message.Trim();

            // check if the message is valid json
            if ((!message.StartsWith("{") || !message.EndsWith("}")) &&
                (!message.StartsWith("[") || !message.EndsWith("]")))
            {
                return;
            }

            JToken jToken;

            try
            {
                jToken = JToken.Parse(message);
            }
            catch (JsonReaderException jex)
            {
                socket.Send("{ \"op\": \"error\", \"error\": \"Unable to parse JSON request. " + JsonConvert.ToString(jex.Message) + "\" }");
                return;
            }
            catch (Exception ex)
            {
                socket.Send("{ \"op\": \"error\", \"error\": \"Exception while parsing JSON request. " + JsonConvert.ToString(ex.Message) + "\" }");
                return;
            }

            if (jToken.Type != JTokenType.Object)
            {
                socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected Object, but encountered " + jToken.Type + "\" }");
                return;
            }

            var jObject = jToken.ToObject <JObject>();

            if (!jObject.ContainsKey("op") || jObject["op"].Type != JTokenType.String)
            {
                socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected 'op' parameter as string.\" }");
                return;
            }

            // block subscriptions
            if (jObject["op"].ToString().Equals("block", StringComparison.CurrentCultureIgnoreCase))
            {
                subscriptionHandler.AddSubscription(socket, new BlockSubscription());
                socket.Send("{ \"op\": \"block\", \"result\": \"ok\" }");
            }
            // block un-subscribe
            else if (jObject["op"].ToString().Equals("rm_block", StringComparison.CurrentCultureIgnoreCase))
            {
                socket.Send(subscriptionHandler.RemoveSubscription(socket, new BlockSubscription())
                    ? "{ \"op\": \"rm_block\", \"result\": \"ok\" }"
                    : "{ \"op\": \"rm_block\", \"result\": \"failed\" }");
            }

            // transaction subscriptions
            else if (jObject["op"].ToString().Equals("transaction", StringComparison.CurrentCultureIgnoreCase))
            {
                subscriptionHandler.AddSubscription(socket, new TransactionSubscription());
                socket.Send("{ \"op\": \"transaction\", \"result\": \"ok\" }");
            }
            // transaction un-subscribe
            else if (jObject["op"].ToString().Equals("rm_transaction", StringComparison.CurrentCultureIgnoreCase))
            {
                socket.Send(subscriptionHandler.RemoveSubscription(socket, new TransactionSubscription())
                    ? "{ \"op\": \"rm_transaction\", \"result\": \"ok\" }"
                    : "{ \"op\": \"rm_transaction\", \"result\": \"failed\" }");
            }

            // address subscriptions
            else if (jObject["op"].ToString().Equals("address", StringComparison.CurrentCultureIgnoreCase) ||
                     jObject["op"].ToString().Equals("rm_address", StringComparison.CurrentCultureIgnoreCase))
            {
                if (!jObject.ContainsKey("address") || jObject["address"].Type != JTokenType.String)
                {
                    socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected 'address' parameter as string.\" }");
                    return;
                }

                // attempt to decode cash address
                try
                {
                    var decoded = CashAddress.DecodeCashAddress(jObject["address"].ToString());

                    if (jObject["op"].ToString().Equals("address", StringComparison.CurrentCultureIgnoreCase))
                    {
                        subscriptionHandler.AddSubscription(socket, new AddressSubscription(decoded));
                        socket.Send("{ \"op\": \"address\", \"result\": \"ok\" }");
                    }

                    else if (jObject["op"].ToString().Equals("rm_address", StringComparison.CurrentCultureIgnoreCase))
                    {
                        socket.Send(!subscriptionHandler.RemoveSubscription(socket, new AddressSubscription(decoded))
                            ? "{ \"op\": \"rm_address\", \"result\": \"failed\" }"
                            : "{ \"op\": \"rm_address\", \"result\": \"ok\" }");
                    }
                }
                catch (CashAddress.CashAddressException e)
                {
                    socket.Send("{ \"op\": \"error\", \"error\": \"" + JsonConvert.ToString(e.Message) + " ... " + JsonConvert.ToString(e.InnerException.Message) + "\" }");
                }
            }

            // op return subscriptions
            else if (jObject["op"].ToString().Equals("opreturn", StringComparison.CurrentCultureIgnoreCase) ||
                     jObject["op"].ToString().Equals("rm_opreturn", StringComparison.CurrentCultureIgnoreCase))
            {
                if (!jObject.ContainsKey("prefix") || jObject["prefix"].Type != JTokenType.String)
                {
                    socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected 'prefix' parameter as string.\" }");
                    return;
                }
                if (!IsValidHexString(jObject["prefix"].ToString()))
                {
                    socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected 'prefix' parameter to be valid hex.\" }");
                    return;
                }
                if (jObject["prefix"].ToString().Length > 32)
                {
                    socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected 'prefix' parameter to be less than 32 hex characters long.\" }");
                    return;
                }

                var prefix = ByteHexConverter.StringToByteArray(jObject["prefix"].ToString());

                if (jObject["op"].ToString().Equals("opreturn", StringComparison.CurrentCultureIgnoreCase))
                {
                    subscriptionHandler.AddSubscription(socket, new OpReturnSubscription(prefix));
                    socket.Send("{ \"op\": \"opreturn\", \"result\": \"ok\" }");
                }
                else if (subscriptionHandler.RemoveSubscription(socket,
                                                                new OpReturnSubscription(prefix)))
                {
                    socket.Send(!subscriptionHandler.RemoveSubscription(socket, new OpReturnSubscription(prefix))
                        ? "{ \"op\": \"rm_opreturn\", \"result\": \"failed\" }"
                        : "{ \"op\": \"rm_opreturn\", \"result\": \"ok\" }");
                }
            }

            else
            {
                // unrecognized op command
                socket.Send("{ \"op\": \"error\", \"error\": \"Error while parsing JSON request. Expected valid 'op' parameter.\" }");
            }
        }
Esempio n. 5
0
 /// <summary>
 ///     Remove a websocket connection
 /// </summary>
 /// <param name="socket"></param>
 public void RemoveSocket(IWebsocketConnection socket)
 {
     lock (_locker)
         _allSockets.Remove(socket);
 }
Esempio n. 6
0
 /// <summary>
 ///     Add a new websocket connection
 /// </summary>
 /// <param name="socket"></param>
 public void AddSocket(IWebsocketConnection socket)
 {
     lock (_locker)
         _allSockets.Add(socket, new List <Subscription>());
 }
Esempio n. 7
0
 /// <summary>
 ///     Remove existing subscription from the given socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="subscription"></param>
 /// <returns></returns>
 public bool RemoveSubscription(IWebsocketConnection socket, Subscription subscription)
 {
     lock (_locker)
         return(_allSockets.TryGetValue(socket, out var list) && list.Remove(subscription));
 }