O documento apresenta os principais recursos do Azure Mobile Services, incluindo monitoramento 24/7, push notifications, armazenamento de dados em SQL, Table Storage e MongoDB, autenticação com Active Directory, Facebook, Twitter e Google, e integração com Office 365 e SharePoint. Demos são apresentados para autenticação e autorização, tarefas agendadas, chamadas de API e integração com Git.
3. Mobile Services
• Monitoramento e gerenciamento 24x7
• SSO com Active Directory, Facebook, Twitter, e Google
• Push notifications
• Dados em SQL, Table Storage, e MongoDB
• Consome Office 365 e SharePoint
• Apps offline podem sincronizar com a núvem
4. Principais Componentes
Envio de Notificações
Lógica no Servidor
Autenticação e Autorização Armazenamento de Dados
Agendamento de Tarefas
Logs e Diagnósticos
Escalabilidade
5. Introdução ao Mobile Services
• Apresentação do Painel de Gerenciamento
• https://manage.windowsazure.com/
• Criação de tabelas
• Download de exemplos de códigos
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-get-started-users/
------------------
<div id="logged-in">
Você está conectado como <span id="login-name"></span>.
<button id="log-out">Fazer logoff</button>
</div>
<div id="logged-out">
Você não está conectado.
<button>Fazer Logon</button>
</div>
------------------
function refreshAuthDisplay() {
var isLoggedIn = client.currentUser !== null;
$("#logged-in").toggle(isLoggedIn);
$("#logged-out").toggle(!isLoggedIn);
if (isLoggedIn) {
$("#login-name").text(client.currentUser.userId);
refreshTodoItems();
}
}
function logIn() {
client.login("facebook").then(refreshAuthDisplay, function(error){
alert(error);
});
}
function logOut() {
client.logout();
refreshAuthDisplay();
$('#summary').html('<strong>You must login to access data.</strong>');
}
// On page init, fetch the data and set up event handlers
$(function () {
refreshAuthDisplay();
$('#summary').html('<strong>You must login to access data.</strong>');
$("#logged-out button").click(logIn);
$("#logged-in button").click(logOut);
});
var updatesTable = tables.getTable('Updates');
var request = require('request');
var twitterUrl = "https://api.twitter.com/1.1/search/tweets.json?q=DebateNaRecord&result_type=recent";
// Get the service configuration module.
var config = require('mobileservice-config');
// Get the stored Twitter consumer key and secret.
var consumerKey = config.twitterConsumerKey,
consumerSecret = config.twitterConsumerSecret
// Get the Twitter access token from app settings.
var accessToken= config.appSettings.TWITTER_ACCESS_TOKEN,
accessTokenSecret = config.appSettings.TWITTER_ACCESS_TOKEN_SECRET;
function GetUpdates() {
// Check what is the last tweet we stored when the job last ran
// and ask Twitter to only give us more recent tweets
appendLastTweetId(
twitterUrl,
function twitterUrlReady(url){
// Create a new request with OAuth credentials.
request.get({
url: url,
oauth: {
consumer_key: consumerKey,
consumer_secret: consumerSecret,
token: accessToken,
token_secret: accessTokenSecret
}},
function (error, response, body) {
if (!error && response.statusCode == 200) {
var results = JSON.parse(body).statuses;
if(results){
console.log('Fetched ' + results.length + ' new results from Twitter');
results.forEach(function (tweet){
if(!filterOutTweet(tweet)){
var update = {
twitterId: tweet.id,
text: tweet.text,
author: tweet.user.screen_name,
date: tweet.created_at
};
updatesTable.insert(update);
}
});
}
} else {
console.error('Could not contact Twitter');
}
});
});
}
// Find the largest (most recent) tweet ID we have already stored
// (if we have stored any) and ask Twitter to only return more
// recent ones
function appendLastTweetId(url, callback){
updatesTable
.orderByDescending('twitterId')
.read({success: function readUpdates(updates){
if(updates.length){
callback(url + '&since_id=' + (updates[0].twitterId + 1));
} else {
callback(url);
}
}});
}
function filterOutTweet(tweet){
// Remove retweets and replies
return (tweet.text.indexOf('RT') === 0 || tweet.to_user_id);
}
http://azure.microsoft.com/pt-br/documentation/articles/mobile-services-html-call-custom-api/
exports.post = function(request, response) {
var mssql = request.service.mssql;
var sql = "UPDATE todoitem SET complete = 1 " +
"WHERE complete = 0; SELECT @@ROWCOUNT as count";
mssql.query(sql, {
success: function(results) {
if(results.length == 1)
response.send(200, results[0]);
}
})
};
exports.get = function(request, response) {
response.send(statusCodes.OK, { message : 'Hello World!' });
};
<button id="buttonCompleteAll">Complete All</button>
var completeAllTodoItems = function () {
// Asynchronously call the custom API using the POST method.
client.invokeApi("completeall", {
body: null,
method: "post"
}).done(function (results) {
var message = results.result.count + " item(s) marked as complete.";
alert(message);
refreshTodoItems();
}, function(error) {
alert(error.message);
});
};
$('#buttonCompleteAll').click(function () {
completeAllTodoItems();
});
var SendGrid = require('sendgrid').SendGrid;
function insert(item, user, request) {
request.execute({
success: function() {
// After the record has been inserted, send the response immediately to the client
request.respond();
// Send the email in the background
sendEmail(item);
}
});
function sendEmail(item) {
var sendgrid = new SendGrid('azure_f043f759701e2a9c5c21b90ef0c3b703@azure.com', 'yhtmFS0wS69jQ59');
sendgrid.send({
to: 'ivan@100loop.com',
from: 'admin@todoitem.com',
subject: 'New to-do item',
text: 'A new to-do was added: ' + item.text
}, function(success, message) {
// If the email failed to send, log it as an error so we can investigate
if (!success) {
console.error(message);
}
});
}
}
http://azure.microsoft.com/pt-br/documentation/articles/mobile-services-html-call-custom-api/
<button id="buttonCompleteAll">Complete All</button>
var completeAllTodoItems = function () {
// Asynchronously call the custom API using the POST method.
client.invokeApi("completeall", {
body: null,
method: "post"
}).done(function (results) {
var message = results.result.count + " item(s) marked as complete.";
alert(message);
refreshTodoItems();
}, function(error) {
alert(error.message);
});
};
$('#buttonCompleteAll').click(function () {
completeAllTodoItems();
});