public override AliyunServiceException UnmarshallException(XmlUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode) { XmlTextReader reader = new XmlTextReader(context.ResponseStream); ErrorResponse errorResponse = new ErrorResponse(); while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if (reader.LocalName == Constants.XML_ROOT_ERROR_RESPONSE) { return(UnmarshallNormalError(reader, innerException, statusCode)); } else { AckMessageException ackMessageException = UnmarshallAckMessageError(reader); ackMessageException.RequestId = context.ResponseData.GetHeaderValue("x-mq-request-id"); return(ackMessageException); } } } return(new MQException(errorResponse.Message, innerException, errorResponse.Code, errorResponse.RequestId, errorResponse.HostId, statusCode)); }
static void ProcessAckError(Exception exception) { // 如果Commit/Rollback时超过了TransCheckImmunityTime(针对发送事务消息的句柄)或者超过10s(针对consumeHalfMessage的句柄)则会失败 if (exception is AckMessageException) { AckMessageException ackExp = (AckMessageException)exception; Console.WriteLine("Ack message fail, RequestId:" + ackExp.RequestId); foreach (AckMessageErrorItem errorItem in ackExp.ErrorItems) { Console.WriteLine("\tErrorHandle:" + errorItem.ReceiptHandle + ",ErrorCode:" + errorItem.ErrorCode + ",ErrorMsg:" + errorItem.ErrorMessage); } } }
private AckMessageException UnmarshallAckMessageError(XmlTextReader reader) { AckMessageException ackMessageException = new AckMessageException(); AckMessageErrorItem item = null; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case Constants.XML_ROOT_ERROR_RESPONSE: item = new AckMessageErrorItem(); break; case Constants.XML_ELEMENT_ERROR_CODE: reader.Read(); item.ErrorCode = reader.Value; break; case Constants.XML_ELEMENT_ERROR_MESSAGE: reader.Read(); item.ErrorMessage = reader.Value; break; case Constants.XML_ELEMENT_RECEIPT_HANDLE: reader.Read(); item.ReceiptHandle = reader.Value; break; } break; case XmlNodeType.EndElement: if (reader.LocalName == Constants.XML_ROOT_ERROR_RESPONSE) { ackMessageException.ErrorItems.Add(item); } break; } } reader.Close(); return(ackMessageException); }
static void Main(string[] args) { // 在当前线程循环消费消息,建议是多开个几个线程并发消费消息 while (true) { try { // 长轮询消费消息 // 长轮询表示如果topic没有消息则请求会在服务端挂住3s,3s内如果有消息可以消费则立即返回 List <Message> messages = null; try { messages = consumer.ConsumeMessage( 3, // 一次最多消费3条(最多可设置为16条) 3 // 长轮询时间3秒(最多可设置为30秒) ); } catch (Exception exp1) { if (exp1 is MessageNotExistException) { Console.WriteLine(Thread.CurrentThread.Name + " No new message, " + ((MessageNotExistException)exp1).RequestId); continue; } Console.WriteLine(exp1); Thread.Sleep(2000); } if (messages == null) { continue; } List <string> handlers = new List <string>(); Console.WriteLine(Thread.CurrentThread.Name + " Receive Messages:"); // 处理业务逻辑 foreach (Message message in messages) { Console.WriteLine(message); Console.WriteLine("Property a is:" + message.GetProperty("a")); handlers.Add(message.ReceiptHandle); } // Message.nextConsumeTime前若不确认消息消费成功,则消息会重复消费 // 消息句柄有时间戳,同一条消息每次消费拿到的都不一样 try { consumer.AckMessage(handlers); Console.WriteLine("Ack message success:"); foreach (string handle in handlers) { Console.Write("\t" + handle); } Console.WriteLine(); } catch (Exception exp2) { // 某些消息的句柄可能超时了会导致确认不成功 if (exp2 is AckMessageException) { AckMessageException ackExp = (AckMessageException)exp2; Console.WriteLine("Ack message fail, RequestId:" + ackExp.RequestId); foreach (AckMessageErrorItem errorItem in ackExp.ErrorItems) { Console.WriteLine("\tErrorHandle:" + errorItem.ReceiptHandle + ",ErrorCode:" + errorItem.ErrorCode + ",ErrorMsg:" + errorItem.ErrorMessage); } } } } catch (Exception ex) { Console.WriteLine(ex); Thread.Sleep(2000); } } }