/// <summary> /// consume message /// </summary> /// <param name="channel">IModel</param> /// <param name="queue">队列名</param> public void ConsumeMessage(IModel channel, string queue) { channel.QueueDeclare(queue, false, false, false, null); var consumer = new DatabaseConsumer(channel, _dataContext); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); ea.EventDataContext.LogDatas.Add(new LogData { Id = message, Log = message }); var res = _dataContext.SaveChanges(); Console.WriteLine(message); channel.BasicAck(ea.DeliveryTag, false); }; string consumerTag = channel.BasicConsume(queue, false, consumer); channel.BasicCancel(consumerTag); //通过这种方式可以关闭该消费者 }
private static void Main(string[] args) { // get internal litedb database filename from app settings var databaseFileName = ConfigurationManager.AppSettings["LiteDBFileName"]; // init the database Database = new DatabaseConsumer(databaseFileName); // get saved subscriptions Subscriptions = Database.GetSubscriptions().ToList(); // get RPC connection params from app settings var rpcURL = ConfigurationManager.AppSettings["RPCURI"]; var rpcUsername = ConfigurationManager.AppSettings["RPCUsername"]; var rpcPassword = ConfigurationManager.AppSettings["RPCPassword"]; // init RPC connection RPCClient = new RPCClient(new Uri(rpcURL), rpcUsername, rpcPassword); // get info for the last block that was processed var lastBlock = Database.GetLastBlock(); var blockCount = RPCClient.GetBlockCount(); // write out of the current block height, and last processed block height Console.Write("Current block: " + blockCount + ". " + (lastBlock == null ? " No previous block data found." : " Last block processed: " + lastBlock.Height)); // if we already have block data, fetch transactions since the last seen block if (lastBlock != null && lastBlock.Height < blockCount) { Console.WriteLine(". processing " + (blockCount - lastBlock.Height) + " blocks..."); // record how long it takes to process the block data var stopWatch = new Stopwatch(); stopWatch.Start(); // look at all blocks from the last block that was processed until the current height for (var blockIndex = lastBlock.Height; blockIndex <= blockCount; blockIndex++) { // fetch raw block data by height var blockHash = RPCClient.GetBlockHash(blockIndex); var blockData = RPCClient.GetBlockData(blockHash); // decode the block var block = new Block(ByteToHex.StringToByteArray(blockData)) { FirstSeen = DateTimeOffset.UtcNow.ToUnixTimeSeconds() }; // add the block to the database Database.EnqueueTask(new DatabaseWrite(block), 0); // process all transactions that occured in the block foreach (var transaction in block.Transactions) { // does this transaction contain an output we are watching? SubscriptionCheck.CheckForSubscription(transaction); } } stopWatch.Stop(); var elapsed = stopWatch.Elapsed; Console.Write("Processed blocks in " + $"{elapsed.Hours:00}:{elapsed.Minutes:00}:{elapsed.Seconds:00}.{elapsed.Milliseconds / 10:00}"); } Console.WriteLine(); // get websocket listen address/port from app settings var websocketListen = ConfigurationManager.AppSettings["WebSocketListen"]; // start websocket server WebSocketServer = new WebSocket.Server(websocketListen); // get ZMQ server address from app settings var zmqServerTX = ConfigurationManager.AppSettings["ZMQPublisherRawTX"]; var zmqServerBlock = ConfigurationManager.AppSettings["ZMQPublisherRawBlock"]; // start ZMQ subscribers new ZMQ.Subscriber(zmqServerTX, "rawtx", new TXConsumer()); new ZMQ.Subscriber(zmqServerBlock, "rawblock", new BlockConsumer()); // skip scanning the mempool if there is no saved block data yet (TODO: maybe it should still scan?) if (lastBlock != null) { // fetch the mempool var memPool = RPCClient.GetMemPool(); Console.WriteLine("Mempool contains " + memPool.Length + " transactions; processing..."); // record how long it takes to process the mempool var stopWatch2 = new Stopwatch(); stopWatch2.Start(); // process all mempool transactions foreach (var txid in memPool) { var rawTransaction = RPCClient.GetRawTransaction(txid); var transaction = new Transaction(rawTransaction) { FirstSeen = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), LastUpdated = DateTimeOffset.UtcNow.ToUnixTimeSeconds() }; // does this transaction contain an output we are watching? SubscriptionCheck.CheckForSubscription(transaction); } stopWatch2.Stop(); var elapsed2 = stopWatch2.Elapsed; Console.WriteLine("Processed mempool in " + $"{elapsed2.Hours:00}:{elapsed2.Minutes:00}:{elapsed2.Seconds:00}.{elapsed2.Milliseconds / 10:00}"); } else { Console.WriteLine("Skipping mempool scan on first run."); } }
private static void Consumer(string brokerList, List <string> topics, string mode) { Console.WriteLine($"Started consumer, Ctrl-C to stop consuming"); ConsumerApp.Interfaces.Consumer consumer; //Modes of the producer //single - each line is write in the console //multi - produces a lot of messages if (String.IsNullOrEmpty(mode)) { mode = ConsumerTypes.Database.ToString(); } else { ConsumerTypes producerType; if (Enum.TryParse(mode, out producerType)) { if (Enum.IsDefined(typeof(ConsumerTypes), mode)) { mode = producerType.ToString(); } else { Console.WriteLine("The producer type passed as argument doesn't exits. mode defaults to multi"); mode = ConsumerTypes.Database.ToString(); } } else { mode = ConsumerTypes.Database.ToString(); } } if (mode == ConsumerTypes.single.ToString()) { consumer = new SimpleConsumer(); } else if (mode == ConsumerTypes.manual.ToString()) { consumer = new ManualConsumer(); } else if (mode == ConsumerTypes.EntityFramework.ToString()) { consumer = new EntityFrameworkConsumer(); } else if (mode == ConsumerTypes.Database.ToString()) { consumer = new DatabaseConsumer(); } else { consumer = new DatabaseConsumer(); } CancellationTokenSource cts = new CancellationTokenSource(); Console.CancelKeyPress += (_, e) => { e.Cancel = true; // prevent the process from terminating. cts.Cancel(); }; consumer.Run(brokerList, topics, cts.Token); // switch (mode) // { // case "subscribe": // Run_Consume(brokerList, topics, cts.Token); // break; // case "manual": // Run_ManualAssign(brokerList, topics, cts.Token); // break; // case "multi": // Run_MultiAssign_Multi(brokerList, topics, cts.Token); // break; // case "multijson": // Run_MultiAssign_Json(brokerList, topics, cts.Token); // break; // default: // PrintUsage(); // break; // } }