选择Asp.Net Web Role,创建名为Thumbnails_WebRole的Web Role项目,选项WorkerRole,创建名为Thumbnail_WorkerRole的Worker Role项目,点击“确定 OK”。
第二步:添加WebRole程序代码
在WebRole程序代码设计部分,我们要完成的任务是:编写Worker Role的功能、设计上传显示界面,完成上传、显示功能,可以说是整个案例代码的核心部分。
我们首先介绍Thumbnails_WorkerRole项目下Work Role的核心代码:
首先要在worker Role短创建缩略图,创建缩略图的方法是:
private Stream CreateThumbnail(Stream input)
{
//代码略
}
{
//代码略
}
重写OnStart方法,代码如下
public override bool OnStart()
{
DiagnosticMonitor.Start("DiagnosticsConnectionString");
#region Setup CloudStorageAccount Configuration Setting Publisher
// This code sets up a handler to update CloudStorageAccount instances when their corresponding
// configuration settings change in the service configuration file.
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
// Provide the configSetter with the initial value
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
RoleEnvironment.Changed += (sender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any((change) => (change.ConfigurationSettingName == configName)))
{
// The corresponding configuration setting has changed, propagate the value
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
{
// In this case, the change to the storage account credentials in the
// service configuration is significant enough that the role needs to be
// recycled in order to use the latest settings. (for example, the
// endpoint has changed)
RoleEnvironment.RequestRecycle();
}
}
};
});
#endregion
return base.OnStart();
}
{
DiagnosticMonitor.Start("DiagnosticsConnectionString");
#region Setup CloudStorageAccount Configuration Setting Publisher
// This code sets up a handler to update CloudStorageAccount instances when their corresponding
// configuration settings change in the service configuration file.
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
// Provide the configSetter with the initial value
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
RoleEnvironment.Changed += (sender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any((change) => (change.ConfigurationSettingName == configName)))
{
// The corresponding configuration setting has changed, propagate the value
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
{
// In this case, the change to the storage account credentials in the
// service configuration is significant enough that the role needs to be
// recycled in order to use the latest settings. (for example, the
// endpoint has changed)
RoleEnvironment.RequestRecycle();
}
}
};
});
#endregion
return base.OnStart();
}
重写Run方法:
public override void Run()
{
//创建云存储账户
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
//创建Blob Container
CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference("photogallery");
//创建队列
CloudQueueClient queueStorage = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueStorage.GetQueueReference("thumbnailmaker");
Trace.TraceInformation("Creating container and queue...");
// If the Start() method throws an exception, the role recycles.
// If this sample is run locally and the development storage tool has not been started, this
// can cause a number of exceptions to be thrown because roles are restarted repeatedly.
// Lets try to create the queue and the container and check whether the storage services are running
// at all.
bool containerAndQueueCreated = false;
while (!containerAndQueueCreated)
{
try
{
container.CreateIfNotExist();
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
permissions = container.GetPermissions();
queue.CreateIfNotExist();
containerAndQueueCreated = true;
}
catch (StorageClientException e)
{
if (e.ErrorCode == StorageErrorCode.TransportError)
{
Trace.TraceError(string.Format("Connect failure! The most likely reason is that the local " +
"Development Storage tool is not running or your storage account configuration is incorrect. " +
"Message: '{0}'", e.Message));
System.Threading.Thread.Sleep(5000);
}
else
{
throw;
}
}
}
Trace.TraceInformation("Listening for queue messages...");
// Now that the queue and the container have been created in the above initialization process, get messages
// from the queue and process them individually.
while (true)
{
try
{
CloudQueueMessage msg = queue.GetMessage();
if (msg != null)
{
string path = msg.AsString;
string thumbnailName = System.IO.Path.GetFileNameWithoutExtension(path) + ".jpg";
Trace.TraceInformation(string.Format("Dequeued '{0}'", path));
CloudBlockBlob content = container.GetBlockBlobReference(path);
CloudBlockBlob thumbnail = container.GetBlockBlobReference("thumbnails/" + thumbnailName);
MemoryStream image = new MemoryStream();
content.DownloadToStream(image);
image.Seek(0, SeekOrigin.Begin);
thumbnail.Properties.ContentType = "image/jpeg";
thumbnail.UploadFromStream(CreateThumbnail(image));
Trace.TraceInformation(string.Format("Done with '{0}'", path));
//删除队列消息
queue.DeleteMessage(msg);
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
catch (Exception e)
{
System.Threading.Thread.Sleep(5000);
Trace.TraceError(string.Format("Exception when processing queue item. Message: '{0}'", e.Message));
}
}
}
{
//创建云存储账户
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
//创建Blob Container
CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference("photogallery");
//创建队列
CloudQueueClient queueStorage = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueStorage.GetQueueReference("thumbnailmaker");
Trace.TraceInformation("Creating container and queue...");
// If the Start() method throws an exception, the role recycles.
// If this sample is run locally and the development storage tool has not been started, this
// can cause a number of exceptions to be thrown because roles are restarted repeatedly.
// Lets try to create the queue and the container and check whether the storage services are running
// at all.
bool containerAndQueueCreated = false;
while (!containerAndQueueCreated)
{
try
{
container.CreateIfNotExist();
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
permissions = container.GetPermissions();
queue.CreateIfNotExist();
containerAndQueueCreated = true;
}
catch (StorageClientException e)
{
if (e.ErrorCode == StorageErrorCode.TransportError)
{
Trace.TraceError(string.Format("Connect failure! The most likely reason is that the local " +
"Development Storage tool is not running or your storage account configuration is incorrect. " +
"Message: '{0}'", e.Message));
System.Threading.Thread.Sleep(5000);
}
else
{
throw;
}
}
}
Trace.TraceInformation("Listening for queue messages...");
// Now that the queue and the container have been created in the above initialization process, get messages
// from the queue and process them individually.
while (true)
{
try
{
CloudQueueMessage msg = queue.GetMessage();
if (msg != null)
{
string path = msg.AsString;
string thumbnailName = System.IO.Path.GetFileNameWithoutExtension(path) + ".jpg";
Trace.TraceInformation(string.Format("Dequeued '{0}'", path));
CloudBlockBlob content = container.GetBlockBlobReference(path);
CloudBlockBlob thumbnail = container.GetBlockBlobReference("thumbnails/" + thumbnailName);
MemoryStream image = new MemoryStream();
content.DownloadToStream(image);
image.Seek(0, SeekOrigin.Begin);
thumbnail.Properties.ContentType = "image/jpeg";
thumbnail.UploadFromStream(CreateThumbnail(image));
Trace.TraceInformation(string.Format("Done with '{0}'", path));
//删除队列消息
queue.DeleteMessage(msg);
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
catch (Exception e)
{
System.Threading.Thread.Sleep(5000);
Trace.TraceError(string.Format("Exception when processing queue item. Message: '{0}'", e.Message));
}
}
}