Criando um projeto Silverlight no Azure

Bruno Sonnino

Microsoft MVP – Client App Dev
Janeiro 2011

Tecnologias: Silverlight, Azure, Asp.net

 

Sumário: Este artigo irá mostrar como criar projetos Silverlight hospedados no Azure, como configurar uma conta no Azure e como fazer um upload para o storage do Azure usando Silverlight

Conteúdo

arrow_down.gifIntrodução
arrow_down.gifCriando uma conta no Azure
arrow_down.gifInstalando as ferramentas de desenvolvimento Azure
arrow_down.gifCriando um projeto Silverlight no Azure
arrow_down.gifCriando um uploader para o Storage do Azure
arrow_down.gifProjeto Silverlight sem custos de computação
arrow_down.gifConclusões
arrow_down.gifSobre o Autor

Introdução

Ultimamente, tenho visto muita gente falando sobre hospedagem na nuvem, computação na nuvem, mas não vejo exemplos de como isso pode ser feito com o Azure. Assim, resolvi pegar o touro à unha e criar não um, mas três projetos Silverlight que são hospedados no Azure: o primeiro é um simples “Hello World”, para mostrar como criar um projeto Silverlight e hospedá-lo no Azure. O segundo é um projeto que envia uma foto para o Storage do Azure e mostra a imagem armazenada lá. O terceiro é um projeto Silverlight que não usa um serviço e não usa os custos de processamento.

Criando uma conta no Azure

Para hospedar nossos projetos no Azure, devemos inicialmente criar uma conta. Normalmente, há a cobrança por tempo de computação, por armazenamento e por tráfego de dados, mas a Microsoft está com uma promoção, chamada Introductory Special, que é gratuita até o 31 de Março de 2011 e dá direito ao seguinte (quantidades mensais):

  • Windows Azure
  • 25 horas de computação
  • 500 MB de storage
  • 10.000 transações
  • SQL Azure
  • 1GB Web Edition database (só para os primeiros três meses)
  • Transferência de dados
  • 500 MB in
  • 500 MB out

Esta oferta vai até o 31 de Março de 2011, assim você tem até esta data para testar gratuitamente o Azure, desde que não ultrapasse estes limites (caso eles sejam ultrapassados, haverá cobrança nos valores normais). 

Note bem: caso você não queira usar o Azure de maneira definitiva (a sua intenção é apenas verificar como é trabalhar com o Azure), você deve cancelar sua conta aberta até o dia 31 de Março de 2011, senão seu uso será cobrado normalmente, como indicado emhttp://www.microsoft.com/windowsazure/offers/popup/popup.aspx?lang=en&locale=en-US&offer=MS-AZR-0001P. Alternativamente, você pode deletar todas suas contas de storage, bd, appfabric  e computação, sem precisar cancelar a conta.

Se você tem uma conta MSDN Premium, pode ativar uma conta gratuita com limites muito maiores:

  • Windows Azure
  • 750 horas de computação
  • 10 GB de storage
  • 1.000.000 transações
  • SQL Azure
  • 3 databases 1GB Web Edition
  • Transferência de dados
  • 2.5 a 7GB in (dependendo da região)
  • 5 a 14GB out (dependendo da região

Para criar a conta do Azure, vá para http://www.microsoft.com/azure e clique em “Sign Up Now”. Selecione a oferta “Introductory Special” e clique em “Buy”. Você deverá entrar com seu LiveID, dar um nome para a assinatura e dar os dados do cartão de crédito para cobrança. Conforme falei anteriormente, não haverá cobrança caso os limites não sejam ultrapassados.

Uma vez criada a conta, você pode então entrar no portal de gerenciamento (que é uma aplicação Silverlight), em https://windows.azure.com.

Portal Windows Azure
Figura 1 – Portal Windows Azure

Instalando as ferramentas de desenvolvimento Azure

O próximo passo é instalar as ferramentas de desenvolvimento para o Azure. O Visual Studio Tools for Azure instala um template de projeto para desenvolvimento Azure e também o simulador Azure.

O simulador permite testar e depurar aplicações Azure sem que seja necessário fazer o deploy: você testa a aplicação em sua  máquina até que a aplicação esteja pronta. Quando ela estiver ok, você coloca ela no Azure para ser executada.

As ferramentas para Azure podem ser baixadas em http://www.microsoft.com/downloads/en/details.aspx?FamilyID=7a1089b6-4050-4307-86c4-9dadaa5ed018&displaylang=en. Antes de instalar as ferramentas, você deverá ativar o IIS em sua máquina, se ele não estiver ativo. As instruções para ativação do IIS estão ao final da página de download.

Ao término da instalação das ferramentas, podemos iniciar o desenvolvimento para a plataforma Azure. É necessário que você inicie o Visual Studio como administrador (clique no ícone do VS com o botão direito e selecione “Run as Administrator”), para poder executar o simulador Azure dentro do Visual Studio.

Criando um projeto Silverlight no Azure

Agora, ao selecionarmos a opção File/New Project, temos uma nova opção, “Cloud”, que permite criar um “Windows Azure Project”.

Tela de um novo projeto Azure
Figura 2 – Tela de um novo projeto Azure

Quando selecionamos o nome do projeto e clicamos em OK, uma nova tela se abre, para selecionarmos o tipo de projeto que queremos criar.

Tipo de projeto a ser criado
Figura 3 – Tipo de projeto a ser criado

Selecionamos então “ASP.NET Web Role” e clicamos no botão “>” para adicionarmos à solução. Se quiséssemos adicionar outros projetos à mesma solução, poderíamos selecioná-los agora, clicando no mesmo botão. Clicando OK, a nova solução é criada, com um projeto e o Web Role.

Solução criada para Windows Azure
Figura 4 – Solução criada para Windows Azure

Em seguida, iremos adicionar um novo projeto Silverlight à solução.  Na solução, clique com o botão direito e selecione “Add/New Project” e adicione um projeto Silverlight. Na tela seguinte, você deve ligar o projeto ao projeto Azure.

Tela ao adicionar um novo projeto Silverlight
Figura 5 – Tela ao adicionar um novo projeto Silverlight

Nesta tela, marque as opções “Add a test page...” e “Make it the start page”, para que a nova página que hospeda o controle Silverlight seja usada como página inicial. Se você não fizer assim, a página “Default.aspx” do projeto Azure será mostrada e você deverá modificá-la manualmente para que o projeto Silverlight seja mostrado.

Clique no botão OK para criar o projeto Silverlight. Agora podemos criar nossa página Silverlight normalmente. Neste projeto, faremos algo muito simples, mudaremos o fundo da aplicação e colocaremos um texto “Hello World”. Em MainPage.xaml, coloque o seguinte código na grid da página (você deve remover a propriedade “Background” existente):

<Grid.Background>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFF5BDBD" Offset="0" />
        <GradientStop Color="White" Offset="0.767" />
    </LinearGradientBrush>
</Grid.Background>
<TextBlock Name="textBlock1" Text="Hello World" FontSize="36"  HorizontalAlignment="Center" VerticalAlignment="Center"/>

Listagem 1

Nosso projeto está pronto. Ele pode ser compilado e executado no simulador, teclando-se F5.

Projeto rodando no simulador Azure
Figura 6 – Projeto rodando no simulador Azure

Agora que nosso programa está pronto e testado, podemos publicá-lo, colocando-o no Azure.  Selecione o projeto Azure (que no nosso caso é WindowsAzureProject1) e selecione “Publish”. A seguinte tela aparece:

Tela para publicação do projeto
Figura 7 – Tela para publicação do projeto

Podemos fazer a carga de maneira automática, selecionando a opção “Deploy your Windows Azure...” e dando nossas credenciais, mas iremos fazer do jeito manual, para mostrar o que acontece. Selecione a opção “Create Service Package Only” e tecle em OK. Uma janela do Explorer é aberta com os arquivos que devem ser distribuídos: um com o pacote do projeto e o outro com o arquivo de configuração.

Vá então para o portal de gerenciamento (https://windows.azure.com) e clique em “Hosted Services”. Clique no botão “New hosted service”. A tela para criar um novo serviço é mostrada:

Criação de um novo serviço
Figura 8 – Criação de um novo serviço

Nesta tela, damos um nome para o nosso serviço, indicamos o prefixo para chamá-lo (quando o projeto estiver carregado, seu endereço será  http://slhelloazure.cloudapp.net) e dizemos quais os arquivos para upload. Ainda aqui, podemos dizer se iremos fazer um deploy para ambiente de produção ou de teste.

Clicando OK, o projeto é validado. No nosso caso teremos um aviso:

Aviso ao fazer o deploy
Figura 9 – Aviso ao fazer o deploy

Este aviso é devido ao fato que criamos o projeto com apenas uma instância e isso faz com que a disponibilidade do serviço possa ser reduzida em caso de falha desta instância. Como queremos apenas ver como é que funciona o projeto Silverlight, podemos desprezar o aviso, clicando em “Yes”.

O upload é feito e o projeto é carregado. Após alguns minutos, o serviço é inicializado e podemos começar a usar normalmente.

Inicializando o serviço
Figura 10 – Inicializando o serviço

Quando o serviço estiver inicializado, você pode chamar a URL http://slhelloazure.cloudapp.net. Você não irá ver a sua aplicação Silverlight (lembram-se da página default.aspx? Ela é chamada quando não navegamos para uma página específica). Para ver a aplicação Silverlight, coloque o nome da página de teste na URL, desta maneira: http://slhelloazure.cloudapp.net/silverlightapplication1testpage.aspx.

Aplicação de teste rodando no Azure.
Figura 11 – Aplicação de teste rodando no Azure.

Agora, algumas observações sobre a cobrança de tempo de computação (que estamos usando aqui):

  • Enquanto o serviço está rodando, o tempo de computação é cobrado. Não basta dar o Stop no serviço, no portal de gerenciamento. Você deve parar o serviço e deletá-lo – senão será cobrado normalmente.
  • Não há cobrança fracionada de horas. Se você subiu um serviço por 15 minutos, será cobrada uma hora de computação.
  • O deploy é contabilizado em “Clock hours”, ou seja,  baseado em relógio. Por exemplo, se você subiu 1 instância às 10:50 e a removeu às 11:15, será cobrado em duas “clock hours”, a primeira do período 10:00 – 10:59 e a segunda do período 11:00 – 11:59. Assim, dê uma olhada no relógio quando for fazer um upload de teste.
  • Um Deployment/Remoção com menos de 5 minutos não é contabilizado.
  • Cada instância do serviço conta independentemente. Se você subir um serviço com 5 instâncias por 1 hora, serão contabilizadas 5 horas de computação.

Este post tem algumas dicas para otimizar seu tempo de computação:  http://blogs.msdn.com/b/dankasun/archive/2010/02/01/windows-azure-billing-starts-today-here-s-some-guidance.aspx

Para evitar que o serviço seja cobrado, paramos o serviço e deletamos. No portal de gerenciamento, selecione o serviço e clique no botão Stop. Quando o serviço estiver parado, clique no botão Delete. Em seguida, clique no Hosted Service que foi criado e clique no botão Delete. O seu status deve mostrar “0 hosted services”.

Portal de gerenciamento sem serviços hosteados
Figura 12 – Portal de gerenciamento sem serviços hosteados

Criando um uploader para o Storage do Azure

Até aqui, criamos uma aplicação muito simples para ver como é hospedar um projeto Silverlight no Azure. Agora iremos fazer algo um pouco mais complexo: um programa que faz o upload de uma foto para o Azure e permite que ela seja visualizada na tela, após o upload. Para esta aplicação, é necessário que seja criado um storage no Azure.

Para isso, devemos ir no portal de gerenciamento e clicar em “New Storage Account”. Abre-se a tela de configuração de novo storage:

Criação de um novo storage
Figura 13 – Criação de um novo storage

Devemos dizer qual a URL para este storage  e sua região. Em seguida, o storage é criado. Para acessá-lo, precisamos de uma chave.

Tela do Storage
Figura 14 – Tela do Storage

Para obtê-la, devemos clicar no botão “View” que está do lado direito da tela, abaixo de “Primary Access Key”. A tela com a chave é aberta e podemos copiá-la para a área de trabalho.
Com o storage criado, podemos criar o nosso projeto. Crie um novo projeto Azure e o projeto Silverlight, da mesma maneira que fizemos anteriormente. Ligue o projeto Silverlight ao projeto Web.
Aqui aparece um pequeno problema: o SDK do Azure é projetado para o framework .net completoe não é compatível com Silverlight. Assim, não podemos fazer o upload diretamente. Temos que fazer em duas fases: um upload para o serviço ASP.NET e, do serviço ASP.NET (que usa o framework completo e pode chamar o SDK do Azure), faremos o upload para o storage.
No projeto Silverlight, criamos a interface em MainPage.xaml:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="35" />
        <RowDefinition Height="*" />
        <RowDefinition Height="35" />
    </Grid.RowDefinitions>
    <Button Margin="5" Content="Upload" Click="Button_Click" />
    <Image x:Name="foto" Grid.Row="1" Margin="5" />
    <TextBox x:Name="txtUrl" Grid.Row="2" Margin="5" IsReadOnly="True"/>
</Grid>

Listagem 2

A tela tem um botão para selecionar o arquivo e fazer o upload, uma TextBox que conterá a URL da imagem e um Image que mostrará a imagem armazenada no Storage do Azure.
Como primeiro passo, devemos criar o código para o clique do botão, que irá fazer o upload do arquivo para o servidor ASP.NET, hospedado no Azure:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var dlg = new OpenFileDialog
           {
               Filter = "Arquivos jpg (*.jpg)|*.jpg|Todos arquivos (*.*)|*.*"
           };
    if (dlg.ShowDialog() != true)
        return;
    UploadFile(dlg.File.OpenRead());
}

Listagem 3

Aqui criamos um OpenFileDialog, que irá pedir o arquivo a ser enviado. Em seguida , chamamos a função UploadFile, que recebe um stream, que é aberto com dlg.File.OpenRead().
A função UploadFile irá usar um WebRequest para transmitir o arquivo e receber a resposta, a URL da imagem. A função é a seguinte:

static void SerializarSoap()
{
    Funcionario f = new Funcionario()
    {
        Nome = "Juliano Aece",
        DataDeNascimento = new DateTime(1986, 02, 03),
        Funcao = "Desenvolvedor",
        Salario = 1000.00M
    };

    using (FileStream fs = new FileStream(@"C:\Temp\funcionario.soap", FileMode.Create))
    {
        SoapFormatter formatter = new SoapFormatter();
        formatter.Serialize(fs, f);
    }
}

Listagem 4 – Método para Serializar em SOAP

E para deserializar, obviamente utilizamos a classe SoapFormatter, conforme listagem 5:

private void ReadCallback(IAsyncResult asynchronousResult)
{
    var request = (HttpWebRequest)asynchronousResult.AsyncState;
    // Pega stream de escrita dos dados
    var postStream = request.EndGetRequestStream(asynchronousResult);
    // Escreve os dados
    postStream.Write(buffer, 0, buffer.Length);
    postStream.Close();
    // Solicita a resposta
    request.BeginGetResponse(ResponseCallback, request);
}

Listagem 5

Da mesma maneira, a resposta é assincrona, iniciada com BeginGetResponse. No callback de resposta, chamamos EndGetResponse e obtemos o stream de resposta com stream.GetResponseStream. Após ler o stream (que contém a URL da imagem), carregamos a imagem no componente Image da janela:

private void ResponseCallback(IAsyncResult asynchronousResult)
{
    var request = (HttpWebRequest)asynchronousResult.AsyncState;
    var resp = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
    // Pega o stream de resposta
    using (var streamResponse = resp.GetResponseStream())
    {
        using (var streamRead = new StreamReader(streamResponse))
        {
            // Lê a url, coloca na TextBox e carrega a imagem
            string responseString = streamRead.ReadToEnd();
            // A interação com componentes deve ser na thread de UI
            Dispatcher.BeginInvoke(() =>
                                        {
                                            txtUrl.Text = responseString;
                                            ShowImage(responseString);
                                        });
            streamRead.Close();
        }
        streamResponse.Close();
    }
    resp.Close();
}

Listagem 6

Note que estamos usando o Dispatcher para garantir que a interação com os componentes Silverlight seja feita na thread de interface. A função ShowImage recebe uma URL e carrega a imagem no componente Image:

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    context.Response.Write(UploadStreamToAzure(context.Request.InputStream));
}

Listagem 7

Antes de carregar a image, verificamos se houve um erro (neste caso, a URL irá começar com “Erro”). Se não houver erro, criamos um BitmapImage e atribuímos a propriedade Source da Image a este BitmapImage.

Resta agora apenas a parte do Asp.net. Aqui iremos receber o stream de dados e salvá-lo, usando as funções do Azure.  No projeto ASP.NET (WebRole1), adicione um novo Generic Handler e chame-o de “receiver.ashx”. Na função ProcessRequest, que irá processar a requisição, coloque o seguinte código:

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    context.Response.Write(UploadStreamToAzure(context.Request.InputStream));
}

Listagem 8

Indicamos que a resposta será no format texto e será o resultado da função UploadStreamToAzure, que faz o upload para o Azure. A função UploadStreamToAzure foi “emprestada” do projeto Windows Azure BlobUploader, um programa WinForms que faz o upload de um blob para o Azure e pode ser obtido em http://winazureblobuploader.codeplex.com/

private static string UploadStreamToAzure(Stream uploadStream)
{
    try
    {
        // Entra com as credenciais do Storage
        var storageAccount =
            new CloudStorageAccount(
                    new StorageCredentialsAccountAndKey("storage", "Chave obtida no portal de gerenciamento"),
                    false // usa http
                );

        // Abre container (cria o diretório se não existir)
        CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobStorage.GetContainerReference("imagens");
        container.CreateIfNotExist();

        // configura container para ter acesso público
        var permissions = container.GetPermissions();
        permissions.PublicAccess = BlobContainerPublicAccessType.Container;
        container.SetPermissions(permissions);

        // Dá um nome único à imagem usando uma Guid
        string uniqueBlobName = string.Format("foto_{0}.jpg", Guid.NewGuid());
        CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
        blob.Properties.ContentType = "jpg";
        blob.UploadFromStream(uploadStream);
        // Retorna a URL da imagem armazenada
        return blob.Uri.AbsoluteUri;
    }
    catch (Exception err)
    {
        // Erro - retorna mensagem de erro, iniciada pela palavra "Erro"
        return "Erro: " + err.Message;
    }
}

Listagem 9

Ao receber o stream, a função passa as credenciais, dando  o nome do storage e a chave que foi obtida no portal de gerenciamento. Em seguida, o storage é aberto e configurado para acesso público. Finalmente, o stream é gravado no Azure usando a função UploadFromStream. Finalmente, a URL de armazenamento é passada como retorno da função, para ser enviada  ao controle Silverlight.
Podemos então executar nosso programa.  Clicamos no botão Upload, selecionamos uma imagem, ela é enviada para o Azure e, em seguida, baixada, para ser mostrada no componente Image.

Uploader em execução
Figura 15 – Uploader em execução

Note uma coisa: embora não estamos no Azure (estamos usando o simulador), nossas imagens estão sendo mandadas para o Storage real do Azure – você pode comprovar isso pela URL mostrada na parte inferior da tela. Se selecionar esta URL e copiá-la, quando colar na barra de endereços do browser, a imagem será mostrada. Se você quiser saber o que há no storage e, eventualmente, apagar de lá, pode usar o programa AzureStorageExplorer, que pode ser obtido em http://azurestorageexplorer.codeplex.com/.

AzureStorageExplorer
Figura 16 – AzureStorageExplorer

Podemos agora fazer o upload de nosso programa para o Azure. Vá no projeto Azure, clique com o botão direito e selecione “Publish”. Desta vez, iremos fazer o upload automático. Selecione a opção “Deploy your Windows Azure...” e, na ComboBox de certificados, selecione New. A seguinte tela é mostrada:

Gerenciamento de credenciais
Figura 17 – Gerenciamento de credenciais

Selecione um cerificado (se você não tiver um, pode criar um Self certificate, o link “Help me set up my credentials” da tela ajuda a fazer isso).
Copie o caminho do certificado e vá para o protal de gerenciamento e selecione “Management Cerificates” e clique Add Certificate. Faça o upload do certificado.
Copie o Subscription ID do portal de gerenciamento de dê um nome para as credenciais
No portal de gerenciamento, vá para Hosted Services e crie um novo Hosted Service, mas selecione “Do not Deploy”
Quando o Serviço estiver criado, volte para o Visual Studio e selecione o nome do Hosted Service na segunda ComboBox, clique em OK quando estiver completo.

Tela de upload completa
Figura 18 – Tela de upload completa

O serviço será compilado, publicado e o deploy será feito automaticamente para o Azure. Você pode verificar isso no portal de gerencaiamento. Quando o deploy estiver completo, você pode executá-lo da mesma maneira que o anterior. Após testar o projeto, se não quiser mantê-lo lá (e ser cobrado por isso), não se esqueça de deletar o serviço no portal de gerenciamento. Uma outra opção de verificação dos serviços é o uso do GreyBox. Este é um programa open source que pode ser obtido em http://greybox.codeplex.com/.

Você deve configurar o arquivo Greybox.exe.config, colocando a SubscriptionID e o Certificate Thumbprint (que podem ser obtidos na tela de certificados do portal de gerenciamento) e iniciar o programa. Ele fica na barra de tarefas, ao lado do relógio e avisa que você tem um deployment ativo. Quando não quiser mais este deployment, pode clicar no ícone com o botão direito do mouse e selecionar “Kill all deployments”.

Projeto Silverlight sem custos de computação

Se seu projeto não necessita de serviços para acesso a dados, você ainda pode hospedá-lo no Azure, sem a necessidade de ter custos de computação, gastando apenas o custo de storage e de transferência de dados. Para isso, faça da seguinte maneira:

  • Crie um novo projeto Silverlight (em uma nova solução)
  • Quando for perguntado o tipo de projeto Silverlight, desmarque a caixa “Host the Silverlight Application in a new WebSite”. Isto fará que o projeto ASP.NETnão seja criado. Será criada apenas uma página HTML que hospeda o controle Silverlight
  • Crie o seu controle Silverlight normalmente
  • Para fazer o upload do projeto, tudo o que você precisa fazer é enviar o arquivo xap do Silverlight e a página HTML. Eles estão no diretório bin/debug (ou bin/release) do projeto
  • Abra o Azure Storage Explorer
  • Crie um novo Container (este passo é opcional, faça isto apenas se quiser separar o projeto Silverlight dos outros containers)
  • Clique no botão Upload e faça o upload do arquivo HTML e do XAP. Pronto. Você já tem seu projeto hospedado no Azure, basta chamar a URL da página HTML

Projeto Silverlight hospedado no Azure
Figura 19 – Projeto Silverlight hospedado no Azure

Conclusões

Como pudemos ver, a criação de projetos que rodam no Azure é bastante fácil, muito semelhante aos projetos que estamos acostumados a criar. O simulador de Azure facilita muito a depuração de programas, fazendo que possam ser testados antes de serem enviados ao Azure. Finalmente, podemos até hospedar nossos projetos Silverlight no storage do Azure, dispensando assim os custos de computação.

Sobre o Autor

Bruno Sonnino é Microsoft MVP (Most Valuable Professional), consultor e desenvolvedor há mais de 20 anos. É autor de 7 livros, escreve artigos para diversas revistas e portais nacionais e estrangeiros. Desenvolveu mais de 40 utilitários para a revista PCMagazine americana. Foi palestrante em diversos eventos, como TechEd 2006, 2007, 2008, 2009 e 2010, Remix 2006 e 2007, nas 6 edições da BorCon Brasil e na 11a. BorCon americana. Ele tem um blog em http://msmvps.com/blogs/bsonnino e pode ser encontrado no twitter @bsonnino.