最近在使用阿里云的消息队列做和第三方对接的处理
阿里云消息队列的官方文档 地址如下:阿里云消息队列官方帮助文档
去该地址下载阿里云提供的sdk 阿里云tcp协议 .net sdk
下载后解压:
这几个引用需要注意:
实际上所需要的就是这个文件夹下面的类和上面的四个引用:
该类下的代码是阿里给出的示例:
下面贴出我封装好的示例:
基础类:
namespace RocketMQCore
{
public class RocketMQConfig
{
public RocketMQConfig(string accessKeyId, string secretAccessKey, string endpoint, string groupId, string instanceId, string topicName)
{
AccessKeyId = accessKeyId;
SecretAccessKey = secretAccessKey;
Endpoint = endpoint;
GroupId = groupId;
InstanceId = instanceId;
TopicName = topicName;
}
/// <summary>
/// AccessKey 阿里云身份验证
/// </summary>
public string AccessKeyId { get; set; }
/// <summary>
/// SecretKey 阿里云身份验证
/// </summary>
public string SecretAccessKey { get; set; }
/// <summary>
/// HTTP接入域名
/// </summary>
public string Endpoint { get; set; }
/// <summary>
/// Topic所属实例ID,默认实例为空
/// </summary>
public string InstanceId { get; set; }
/// <summary>
/// 所属的 Topic
/// </summary>
public string TopicName { get; set; }
/// <summary>
/// Consumer ID(Group ID)
/// </summary>
public string GroupId { get; set; }
/// <summary>
/// 消息标签,二级消息类型,用来进一步区分某个Topic下的消息分类。更多信息,请参见Topic与Tag最佳实践。
/// </summary>
//public string Tag { get; set; }
}
}
发送消息方法:
public class SendMessages
{
public RocketMQConfig Config
{
get;
set;
}
public SendMessages(RocketMQConfig config)
{
Config = config;
}
/// <summary>
/// 发布消息
/// </summary>
/// <param name="Tag"></param>
/// <param name="MessageBoby"></param>
/// <param name="ShardingKey"></param>
public void SendMessage(string Tag, string MessageBoby,string shardingKey)
{
// 配置您的账号,以下设置均可从控制台获取。
ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
// AccessKey ID阿里云身份验证,在阿里云用户信息管理控制台创建。
factoryInfo.setFactoryProperty(ONSFactoryProperty.AccessKey, Config.AccessKeyId);
// AccessKey Secret阿里云身份验证,在阿里云用户信息管理控制台创建。
factoryInfo.setFactoryProperty(ONSFactoryProperty.SecretKey, Config.SecretAccessKey);
// 您在控制台创建的Group ID。
factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, Config.GroupId);
// 您在控制台创建的Topic。
factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, Config.TopicName);
// 设置TCP接入域名,进入控制台的实例详情页面的TCP协议客户端接入点区域查看。
factoryInfo.setFactoryProperty(ONSFactoryProperty.NAMESRV_ADDR, Config.Endpoint);
// 设置日志路径。
//factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");
// 创建生产者实例。
// 说明:生产者实例是线程安全的,可用于发送不同Topic的消息。基本上,您每一个线程只需要一个生产者实例。
OrderProducer producer = ONSFactory.getInstance().createOrderProducer(factoryInfo);
// 启动客户端实例。
producer.start();
try
{
//如果消息中包含中文会出现乱码问题 下面两句代码是处理中文乱码问题的
byte[] bytes = Encoding.UTF8.GetBytes(MessageBoby);//中文encode
var body = Newtonsoft.Json.JsonConvert.SerializeObject(bytes);
Message msg = new Message(factoryInfo.getPublishTopics(), Tag, body);
SendResultONS sendResult = producer.send(msg, shardingKey);
Console.WriteLine("send success {0}", sendResult.getMessageId());
}
catch (Exception ex)
{
Console.WriteLine("send failure{0}", ex.ToString());
}
}
}
订阅消息方法:
public class ConsumptionMessages
{
public RocketMQConfig Config
{
get;
set;
}
public ConsumptionMessages(RocketMQConfig config)
{
Config = config;
}
//订阅消息
public void ConsumptionMessage(Action<string, string> Message)
{
// 配置您的账号,以下设置均可从控制台获取。
ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
// AccessKey ID阿里云身份验证,在阿里云用户信息管理控制台创建。
factoryInfo.setFactoryProperty(ONSFactoryProperty.AccessKey, Config.AccessKeyId);
// AccessKey Secret阿里云身份验证,在阿里云用户信息管理控制台创建。
factoryInfo.setFactoryProperty(ONSFactoryProperty.SecretKey, Config.SecretAccessKey);
// 您在控制台创建的Group ID。
factoryInfo.setFactoryProperty(ONSFactoryProperty.ConsumerId, Config.GroupId);
// 您在控制台创建的Topic。
factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, Config.TopicName);
// 设置TCP接入域名,进入控制台的实例详情页面的TCP协议客户端接入点区域查看。
factoryInfo.setFactoryProperty(ONSFactoryProperty.NAMESRV_ADDR, Config.Endpoint);
// 设置日志路径。
//factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");
// 集群订阅方式设置(不设置的情况下,默认为集群订阅方式)
factoryInfo.setFactoryProperty(ONSFactoryProperty.MessageModel, ONSFactoryProperty.CLUSTERING);
//创建消费者实例。
OrderConsumer consumer = ONSFactory.getInstance().createOrderConsumer(factoryInfo);
// 订阅Topic。
consumer.subscribe(factoryInfo.getPublishTopics(), "*", new MsgOrderListener(Message));
// 启动消费者实例。
consumer.start();
while (true)
{
var key = Console.ReadKey().Key;
if (key == ConsoleKey.Escape) break;
}
// 让主线程睡眠一段时间。
//Thread.Sleep(30000);
// 不再使用时,关闭消费者实例。
consumer.shutdown();
//Console.ReadKey();
}
}
public class MsgOrderListener : MessageOrderListener
{
public Action<string,string> MessageDelegate { get; set; }
public MsgOrderListener(Action<string,string> messageDelegate)
{
this.MessageDelegate = messageDelegate;
}
~MsgOrderListener()
{
}
public override ons.OrderAction consume(Message value, ConsumeOrderContext context)
{
Byte[] text = Newtonsoft.Json.JsonConvert.DeserializeObject<Byte[]>(value.getBody());
var body = Encoding.UTF8.GetString(text);
MessageDelegate(body,value.getTag());
return ons.OrderAction.Success;
}
}
在实际的项目应用中 对订阅的消息进行处理 比如我方的生产数据需要同步至第三方 在产生数据的地方进行埋点 即消息的发送 在与第三方的对接程序中进行消息的订阅并且转为第三方的格式传送过去 还需根据第三方的同步结果进行订阅消息的处理 例如该消息是否同步成功 如果同步成功 则该消息订阅成功 同步失败 则消息队列需要回滚 重新发送该消息 如果数据不符合对接的格式 对消息是抛弃还是算为订阅成功 这些场景需要用到sdk中的 OrderAction 类进行处理
例如:
var rocketMQConfig = new RocketMQConfig(accessKeyId, secretAccessKey, endpoint, groupId, null, topicName);
var consumptionMessages = new RocketMQCore.ConsumptionMessages(rocketMQConfig);
consumptionMessages.ConsumptionMessage(PushMessage);
public static OrderAction PushMessage(string message, string tag)
{
try
{
//订阅消息的message进行处理
//处理结果
var result;
if (result == true)
{
return ons.OrderAction.Success;
}
else
{
Console.WriteLine("推送失败, 队列回滚," + message);
return ons.OrderAction.Suspend;
}
}
catch (Exception ex)
{
//todo:记录错误日志
Console.WriteLine("序列化消息失败,消息无效, 消息抛弃。消息内容:" + message);
//todo:这里要考虑是否抛弃,先抛弃,后面再说
return ons.OrderAction.Success;
}
}
上面就是一个简单的实例 仅供参考 如有不对 多多交流