有需求就有对策就有市场。
由于公司global的policy,导致对公司外发邮件的service必须要绑定到固定的ip地址,所以别的程序需要调用发邮件程序时,问题就来了,如何在azure上跨service进行work role的调用呢?(work role和web role是两个不同的东西,主要区别在work role是每个单独的不依附与web application,web role则不是)
微软的解决方案有几:
1, 目前发送Email的Cloud Service的workrole同时实现接收发送email的请求,可以有多种接收请求的模式:
a) 通过Azure Service Bus Queue实现,需要发送email的应用将发生的信息打包发送到指定的Azure Service Bus Queue,workrole会侦听该queue,有信息到时接收信息,并触发email发送功能
b) 通过TCP或HTTP协议对外提供侦听服务,该协议的侦听端口通过Cloud Service的endpoint对外开放,需要发送email的应用通过这些服务端口向该workrole发送信息,通知workrole发送email
c) (不推荐,需前期部署时就进行分配)watch out net
此次贪图方便,选了方案一:利用queue进行监听,并触发Email发送功能
Azure Service Bus Queue是一个云端的消息队列PAAS服务,可以参考以下的文档来创建和开发Service Bus Queue的功能:
1, 管理和初步Queue代码:https://www.azure.cn/documentation/articles/service-bus-dotnet-how-to-use-queues/
2, Service Bus开发指南:https://www.azure.cn/documentation/articles/service-bus-create-queues/
3, 样例代码:https://www.azure.cn/documentation/articles/service-bus-samples/
首先在请求的project中web.config配置:
1 <appSettings> 2 <add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://xxx.servicebus.chinacloudapi.cn;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxx" /> 3 </appSettings>
发送请求的代码:
1 string connectionString = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"]; 2 3 var namespaceManager = 4 NamespaceManager.CreateFromConnectionString(connectionString); 5 if (!namespaceManager.QueueExists("EmailQueue")) 6 { 7 namespaceManager.CreateQueue("EmailQueue"); 8 } 9 //queue.AddMessageAsync(new CloudQueueMessage(message)); 10 QueueClient Client = 11 QueueClient.CreateFromConnectionString(connectionString, "EmailQueue"); 12 13 // Create message, passing a string message for the body. 14 BrokeredMessage message = new BrokeredMessage("Email Message"); 15 16 // Set some addtional custom app-specific properties. 17 message.Properties["sender"] = sender; 18 message.Properties["subject"] = mailSubject; 19 message.Properties["address"] = mailAddress; 20 message.Properties["body"] = mailBody; 21 22 try 23 { 24 // Send message to the queue. 25 Client.Send(message); 26 } 27 catch (Exception ex) 28 { 29 throw ex; 30 }
接收service的app.config配置:
1 <appSettings> 2 <!-- Service Bus specific app setings for messaging connections --> 3 <add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://xxx.servicebus.chinacloudapi.cn;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxx" /> 4 </appSettings>
接收的程序代码:
1 private void RunServiceBus() 2 { 3 string connectionString = 4 CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); 5 Microsoft.ServiceBus.Messaging.QueueClient Client = 6 Microsoft.ServiceBus.Messaging.QueueClient.CreateFromConnectionString(connectionString, "EmailQueue"); 7 8 // Configure the callback options. 9 OnMessageOptions options = new OnMessageOptions(); 10 options.AutoComplete = false; 11 options.AutoRenewTimeout = TimeSpan.FromMinutes(1); 12 13 string sender = string.Empty; 14 string mailSubject = string.Empty; 15 string mailAddress = string.Empty; 16 string mailBody = string.Empty; 17 18 // Callback to handle received messages. 19 Client.OnMessage((message) => 20 { 21 try 22 { 23 // Process message from queue. 24 sender = message.Properties["sender"].ToString(); 25 mailSubject = message.Properties["subject"].ToString(); 26 mailAddress = message.Properties["address"].ToString(); 27 mailBody = message.Properties["body"].ToString(); 28 SendEmail(sender, mailSubject, mailAddress, mailBody); 29 30 // Remove message from queue. 31 message.Complete(); 32 } 33 catch (Exception) 34 { 35 // Indicates a problem, unlock message in queue. 36 message.Abandon(); 37 } 38 }, options); 39 40 }