Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
İnsan etkileşimi düzeni, devam etmeden önce bir kişinin girişini duraklatan ve bekleyen iş akışlarını açıklar. Desen onay iş akışları, çok faktörlü kimlik doğrulaması ve bir kişinin zaman sınırı içinde yanıt verdiği tüm senaryolar için kullanışlıdır.
Desen yüksek düzeyde aşağıdaki gibi çalışır:
- Orkestratör, bir kişiyi bilgilendirmek için bir etkinlik çağırır (SMS kodu göndererek, onaylayıcıya e-posta göndererek vb.).
- Orchestrator dayanıklı bir zamanlayıcı başlatır ve aynı anda bir kişiden gelen dış olayı bekler.
- Zamanlayıcı tetiklemeden önce kişi yanıt verirse, düzenleyici yanıtı işler.
- Zamanlayıcı ilk önce tetiklenirse, düzenleyici zaman aşımını işler (örneğin, isteği reddederek).
Bu makalede:
- İnsan etkileşimi senaryosuna genel bakış - Bu desenin neden önemli olduğu
- Düzenleyiciyi tanımlama - Timer-vs-event yarışını uygulama
- Etkinlikleri tanımlama - Bildirim gönderme ve sonuçları işleme
- İnsan etkileşimi örneğini çalıştırma - İş akışını uçtan uca test etme
Uyarı
Dayanıklı İşlevler ve Dayanıklı Görev SDK'sı özetleri farklı senaryolarla aynı deseni gösterir: Dayanıklı İşlevler SMS telefon doğrulaması örneği kullanırken Dayanıklı Görev SDK'ları bir uygulama iş akışı örneği kullanır.
Bu örnek, insan etkileşimi içeren bir Dayanıklı İşlevler düzenlemesi oluşturmayı gösterir. Örnek, SMS tabanlı bir telefon doğrulama sistemi uygular. Telefon numarası doğrulama ve çok faktörlü kimlik doğrulaması (MFA) akışlarında yaygındır.
Uyarı
C#, JavaScript ve Python için tam kod örnekleri sağlanır. PowerShell ve Java örnekleri şu anda kullanılamıyor.
Uyarı
Azure İşlevleri için Node.js programlama modelinin 4. sürümü genel olarak kullanılabilir. v4 modeli, JavaScript ve TypeScript geliştiricileri için daha esnek ve sezgisel bir deneyim sağlamak üzere tasarlanmıştır. v3 ile v4 arasındaki farklar hakkında daha fazla bilgi için geçiş kılavuzuna bakın.
Aşağıdaki kod parçacıklarında JavaScript (PM4), yeni deneyim olan v4 programlama modelini belirtir.
Önkoşullar
- Hızlı başlangıç makalesini tamamlama
- GitHub'dan örnek projesini kopyalama veya indirme (işlem içi modeli kullanır)
Bu makalede, Dayanıklı Görev SDK'larını kullanarak insan etkileşimi deseninin nasıl uygulandığı gösterilmektedir. Örnek, bir orkestrasyonun devam etmeden önce bir kişinin bir isteği onaylamasını veya reddetmesini beklediği bir onay iş akışı uygular.
İnsan etkileşimi senaryosuna genel bakış
Telefon doğrulaması, uygulamanızı kullanan kişilerin spam gönderen olmadığını ve sağladıkları telefon numarasını denetlediklerini doğrulamaya yardımcı olur. Çok faktörlü kimlik doğrulaması, hesapları korumanın yaygın bir yoludur. Kendi telefon doğrulamanızı oluşturmak için bir kişiyle durumlu etkileşim gerekir. Kullanıcı genellikle bir kod (örneğin, dört basamaklı bir sayı) alır ve makul bir süre içinde yanıt vermesi gerekir.
Standart Azure İşlevleri durum bilgisi yoktur (diğer birçok bulut uç noktası gibi), bu tür etkileşimler durumu bir veritabanında veya başka bir kalıcı depoda depolamanızı gerektirir. Ayrıca etkileşimi birden çok işleve böler ve eşgüdümlü olarak düzenlersiniz. Örneğin, bir işlev bir kod oluşturur, depolar ve kullanıcının telefonuna gönderir. Başka bir işlev kullanıcının yanıtını alır ve kodu doğrulamak için özgün istekle eşler. Güvenliği korumaya yardımcı olmak için zaman aşımı ekleyin. Bu iş akışı hızla karmaşıklaşır.
Dayanıklı İşlevler bu senaryonun karmaşıklığını azaltır. Bu örnekte, bir düzenleyici işlev, durum bilgili etkileşimi dış veri deposu kullanmaksızın yönetir. Orchestrator işlevleri dayanıklı olduğundan, bu etkileşimli akışlar son derece güvenilirdir.
Onay iş akışları, devam etmeden önce bir isteğin bir insan tarafından gözden geçirilmesi gereken iş uygulamalarında yaygındır. İş akışı gereksinimleri şunlardır:
- Bir insan yanıtı için süresiz veya zaman aşımına kadar bekleyin
- Hem onay hem de reddetme sonuçlarını işleme
- Yanıt alınmadığında destek zaman aşımları
- İstek sahibinin ilerlemeyi kontrol edebilmesi için durum takibi yapın
Dayanıklı Görev SDK'ları aşağıdakilerle bu senaryoyu basitleştirir:
- Dış olaylar: Düzenleme, bir dış sistem veya kullanıcı tarafından tetiklenen bir olayı duraklatabilir ve bekleyebilir
- Dayanıklı zamanlayıcılar: Yanıt alınamazsa devreye giren bir zaman aşımı ayarlamak
- Özel durum: Geçerli iş akışı durumunu izleme ve istemcilere sunma
Twilio entegrasyonunu yapılandırma
Bu örnek, cep telefonuna SMS mesajları göndermek için Twilio hizmetini kullanmayı içerir. Azure İşlevleri zaten Twilio bağlaması aracılığıyla Twilio desteğine sahiptir ve örnek bu özelliği kullanır.
İhtiyacınız olan ilk şey bir Twilio hesabıdır. adresinde https://www.twilio.com/try-twilioücretsiz bir tane oluşturabilirsiniz. Hesabınız olduktan sonra aşağıdaki üç uygulama ayarlarını işlev uygulamanıza ekleyin.
| Uygulama ayarı adı | Değer açıklaması |
|---|---|
| TwilioAccountSid | Twilio hesabınızın SID değeri |
| TwilioAuthToken | Twilio hesabınız için Kimlik Doğrulama belirteci |
| TwilioPhoneNumber | Twilio hesabınızla ilişkili telefon numarası. Bu, SMS iletileri göndermek için kullanılır. |
Düzenleyiciyi tanımlama
E4_SmsPhoneVerification orchestrator işlevi
[FunctionName("E4_SmsPhoneVerification")]
public static async Task<bool> Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
string phoneNumber = context.GetInput<string>();
if (string.IsNullOrEmpty(phoneNumber))
{
throw new ArgumentNullException(
nameof(phoneNumber),
"A phone number input is required.");
}
int challengeCode = await context.CallActivityAsync<int>(
"E4_SendSmsChallenge",
phoneNumber);
using (var timeoutCts = new CancellationTokenSource())
{
// The user has 90 seconds to respond with the code they received in the SMS message.
DateTime expiration = context.CurrentUtcDateTime.AddSeconds(90);
Task timeoutTask = context.CreateTimer(expiration, timeoutCts.Token);
bool authorized = false;
for (int retryCount = 0; retryCount <= 3; retryCount++)
{
Task<int> challengeResponseTask =
context.WaitForExternalEvent<int>("SmsChallengeResponse");
Task winner = await Task.WhenAny(challengeResponseTask, timeoutTask);
if (winner == challengeResponseTask)
{
// We got back a response! Compare it to the challenge code.
if (challengeResponseTask.Result == challengeCode)
{
authorized = true;
break;
}
}
else
{
// Timeout expired
break;
}
}
if (!timeoutTask.IsCompleted)
{
// All pending timers must be complete or canceled before the function exits.
timeoutCts.Cancel();
}
return authorized;
}
}
Uyarı
İlk başta belirgin olmayabilir, ancak bu düzenleyici belirlenimci düzenleme kısıtlamasını ihlal etmez. Bu belirleyicidir çünkü CurrentUtcDateTime özelliği zamanlayıcı süre sonu süresini hesaplar ve orchestrator kodunda bu noktadaki her yeniden yürütmede aynı değeri döndürür. Bu davranış, winner öğesinin Task.WhenAny işlevine yapılan her yinelenen çağrıda aynı olmasını garanti eder.
Bu düzenleyici işlevi başlatıldıktan sonra aşağıdakileri yapar:
- SMS bildirimi göndermek için bir telefon numarası alır.
- Kullanıcıya SMS iletisi göndermek için E4_SendSmsChallenge çağırır ve beklenen dört basamaklı sınama kodunu döndürür.
- Geçerli saatten 90 saniye sonra tetikleyen dayanıklı bir zamanlayıcı oluşturur.
- Zamanlayıcıya paralel olarak, kullanıcıdan gelen bir SmsChallengeResponse olayını bekler.
Kullanıcı dört basamaklı kod içeren bir SMS iletisi alır. Doğrulamayı tamamlamak için orchestrator örneğine aynı kodu göndermek için 90 saniyeleri vardır. Yanlış kodu gönderirlerse, aynı 90 saniyelik pencerede üç deneme daha yaparlar.
Uyarı
Artık ihtiyacınız olmayan zamanlayıcıları iptal edin. Yukarıdaki örnekte düzenleme, bir sınama yanıtı kabul ettiğinde zamanlayıcıyı iptal eder.
Orkestratör bir onay isteği gönderir, ardından bir insan yanıtı veya zaman aşımı bekler.
using Microsoft.DurableTask;
using System;
using System.Threading;
using System.Threading.Tasks;
[DurableTask(nameof(ApprovalOrchestration))]
public class ApprovalOrchestration : TaskOrchestrator<ApprovalRequestData, ApprovalResult>
{
public override async Task<ApprovalResult> RunAsync(
TaskOrchestrationContext context, ApprovalRequestData input)
{
string requestId = input.RequestId;
double timeoutHours = input.TimeoutHours;
// Step 1: Submit the approval request (notify approver)
SubmissionResult submissionResult = await context.CallActivityAsync<SubmissionResult>(
nameof(SubmitApprovalRequestActivity), input);
// Make the status available via custom status
context.SetCustomStatus(submissionResult);
// Step 2: Create a durable timer for the timeout
DateTime timeoutDeadline = context.CurrentUtcDateTime.AddHours(timeoutHours);
using var timeoutCts = new CancellationTokenSource();
Task timeoutTask = context.CreateTimer(timeoutDeadline, timeoutCts.Token);
// Step 3: Wait for an external event (approval/rejection)
Task<ApprovalResponseData> approvalTask = context.WaitForExternalEvent<ApprovalResponseData>(
"approval_response");
// Step 4: Wait for either the timeout or the approval response
Task completedTask = await Task.WhenAny(approvalTask, timeoutTask);
// Step 5: Process based on which task completed
ApprovalResult result;
if (completedTask == approvalTask)
{
// Human responded in time - cancel the timeout timer
timeoutCts.Cancel();
ApprovalResponseData approvalData = approvalTask.Result;
// Process the approval
result = await context.CallActivityAsync<ApprovalResult>(
nameof(ProcessApprovalActivity),
new ProcessApprovalInput
{
RequestId = requestId,
IsApproved = approvalData.IsApproved,
Approver = approvalData.Approver
});
}
else
{
// Timeout occurred
result = new ApprovalResult
{
RequestId = requestId,
Status = "Timeout",
ProcessedAt = context.CurrentUtcDateTime.ToString("o")
};
}
return result;
}
}
Bu düzenleyici aşağıdaki eylemleri gerçekleştirir:
- Onaylayıcıyı bilgilendiren bir etkinliği çağırarak onay isteğini gönderir.
- İstemcilerin ilerleme durumunu izleyebilmesi için özel durumu ayarlar.
- Zaman aşımı süresi için dayanıklı bir zamanlayıcı oluşturur.
- Onaylayanın tetiklediği bir dış olayı (
approval_response) bekler. - İlk tamamlananı beklemek için
WhenAny,when_anyveyaanyOfkullanır: onaylama veya zaman aşımı. - Hangi görevin tamamlandığına bağlı olarak sonucu işler.
Uyarı
Artık ihtiyacınız olmayan zamanlayıcıları iptal edin. C# örneğinde düzenleme, onay aldığında zaman aşımı zamanlayıcısını iptal eder.
Etkinlikleri tanımlama
E4_SendSmsChallenge etkinlik işlevi
E4_SendSmsChallenge işlevi, kullanıcıya dört basamaklı bir kod içeren bir SMS iletisi göndermek için Twilio bağlamasını kullanır.
[FunctionName("E4_SendSmsChallenge")]
public static int SendSmsChallenge(
[ActivityTrigger] string phoneNumber,
ILogger log,
[TwilioSms(AccountSidSetting = "TwilioAccountSid", AuthTokenSetting = "TwilioAuthToken", From = "%TwilioPhoneNumber%")]
out CreateMessageOptions message)
{
// Get a random number generator with a random seed (not time-based)
var rand = new Random(Guid.NewGuid().GetHashCode());
int challengeCode = rand.Next(10000);
log.LogInformation($"Sending verification code {challengeCode} to {phoneNumber}.");
message = new CreateMessageOptions(new PhoneNumber(phoneNumber));
message.Body = $"Your verification code is {challengeCode:0000}";
return challengeCode;
}
Uyarı
Örneği çalıştırmak için Microsoft.Azure.WebJobs.Extensions.Twilio NuGet paketini yükleyin. Sürüm çakışmasına ve derleme hatasına neden olabileceğinden ana Twilio NuGet paketini yüklemeyin.
Etkinlikler onay isteğini gönderir ve yanıtı işler.
Onay isteği etkinliğini gönderme
using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
[DurableTask(nameof(SubmitApprovalRequestActivity))]
public class SubmitApprovalRequestActivity : TaskActivity<ApprovalRequestData, SubmissionResult>
{
private readonly ILogger<SubmitApprovalRequestActivity> _logger;
public SubmitApprovalRequestActivity(ILogger<SubmitApprovalRequestActivity> logger)
{
_logger = logger;
}
public override Task<SubmissionResult> RunAsync(
TaskActivityContext context, ApprovalRequestData input)
{
_logger.LogInformation(
"Submitting approval request {RequestId} from {Requester} for {Item}",
input.RequestId, input.Requester, input.Item);
// In a real system, this would send an email, notification, or update a database
var result = new SubmissionResult
{
RequestId = input.RequestId,
Status = "Pending",
SubmittedAt = DateTime.UtcNow.ToString("o"),
ApprovalUrl = $"http://localhost:8000/api/approvals/{input.RequestId}"
};
return Task.FromResult(result);
}
}
İşlem onayı etkinliği
using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
[DurableTask(nameof(ProcessApprovalActivity))]
public class ProcessApprovalActivity : TaskActivity<ProcessApprovalInput, ApprovalResult>
{
private readonly ILogger<ProcessApprovalActivity> _logger;
public ProcessApprovalActivity(ILogger<ProcessApprovalActivity> logger)
{
_logger = logger;
}
public override Task<ApprovalResult> RunAsync(
TaskActivityContext context, ProcessApprovalInput input)
{
string status = input.IsApproved ? "Approved" : "Rejected";
_logger.LogInformation(
"Processing {Status} request {RequestId} by {Approver}",
status, input.RequestId, input.Approver);
// In a real system, this would update a database, trigger workflows, etc.
var result = new ApprovalResult
{
RequestId = input.RequestId,
Status = status,
ProcessedAt = DateTime.UtcNow.ToString("o"),
Approver = input.Approver
};
return Task.FromResult(result);
}
}
// Data classes
public class ApprovalRequestData
{
public string RequestId { get; set; } = string.Empty;
public string Requester { get; set; } = string.Empty;
public string Item { get; set; } = string.Empty;
public double TimeoutHours { get; set; } = 24.0;
}
public class ApprovalResponseData
{
public bool IsApproved { get; set; }
public string Approver { get; set; } = string.Empty;
}
public class SubmissionResult
{
public string RequestId { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string SubmittedAt { get; set; } = string.Empty;
public string ApprovalUrl { get; set; } = string.Empty;
}
public class ProcessApprovalInput
{
public string RequestId { get; set; } = string.Empty;
public bool IsApproved { get; set; }
public string Approver { get; set; } = string.Empty;
}
public class ApprovalResult
{
public string RequestId { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string ProcessedAt { get; set; } = string.Empty;
public string? Approver { get; set; }
}
İnsan etkileşimi örneğini çalıştırma
Aşağıdaki HTTP POST isteğini göndererek düzenlemeyi başlatmak için örnekteki HTTP ile tetiklenen işlevleri kullanın:
POST http://{host}/orchestrators/E4_SmsPhoneVerification
Content-Length: 14
Content-Type: application/json
"+1425XXXXXXX"
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
{"id":"741c65651d4c40cea29acdd5bb47baf1",
"sendEventPostUri":"http://{host}/runtime/webhooks/durabletask/instances/741c65651d4c40cea29acdd5bb47baf1/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}",
"statusQueryGetUri":"http://{host}/runtime/webhooks/durabletask/instances/741c65651d4c40cea29acdd5bb47baf1?taskHub=...&code={systemKey}",
"terminatePostUri":"http://{host}/runtime/webhooks/durabletask/instances/741c65651d4c40cea29acdd5bb47baf1/terminate?reason={text}&taskHub=...&code={systemKey}"}
Orchestrator işlevi telefon numarasını alır ve rastgele oluşturulan 4 basamaklı doğrulama koduyla bu numaraya hemen bir SMS iletisi gönderir. Örneğin, 2168. İşlev daha sonra yanıt için 90 saniye bekler.
Kodu yanıtlamak için başka bir işlevde RaiseEventAsync (.NET) veya raiseEvent (JavaScript ve TypeScript) kullanın veya 202 yanıtında sendEventPostUri HTTP POST uç noktasını çağırın.
{eventName} değerini SmsChallengeResponse ile değiştirin.
POST http://{host}/runtime/webhooks/durabletask/instances/741c65651d4c40cea29acdd5bb47baf1/raiseEvent/SmsChallengeResponse?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
Content-Length: 4
Content-Type: application/json
2168
Zamanlayıcının süresi dolmadan önce olayı gönderirseniz, orkestrasyon tamamlanır ve output alanı true olarak ayarlanır, bu da doğrulamanın başarılı olduğunu gösterir.
GET http://{host}/runtime/webhooks/durabletask/instances/741c65651d4c40cea29acdd5bb47baf1?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
HTTP/1.1 200 OK
Content-Length: 144
Content-Type: application/json; charset=utf-8
{"runtimeStatus":"Completed","input":"+1425XXXXXXX","output":true,"createdTime":"2026-04-23T19:10:49Z","lastUpdatedTime":"2026-04-23T19:12:23Z"}
Süreölçerin süresi dolarsa veya dört kez yanlış kod girerseniz, durumunu sorgulayın. output değeri false olarak ayarlanmışsa, bu telefon doğrulamasının başarısız olduğunu gösterir.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 145
{"runtimeStatus":"Completed","input":"+1425XXXXXXX","output":false,"createdTime":"2026-04-23T19:20:49Z","lastUpdatedTime":"2026-04-23T19:22:23Z"}
Örneği çalıştırmak için:
Yerel geliştirme için Dayanıklı Görev Zamanlayıcı öykünücüsü'ne başlayın. Docker yüklü olmalıdır.
docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latestDüzenleyiciyi ve etkinlikleri kaydetmek için çalışanı başlatın.
Bir onay iş akışı zamanlamak ve olayları göndermek için istemciyi çalıştırın.
using System;
using System.Threading.Tasks;
var client = DurableTaskClientBuilder.UseDurableTaskScheduler(connectionString).Build();
// Schedule the approval workflow
var input = new ApprovalRequestData
{
RequestId = "request-" + Guid.NewGuid().ToString(),
Requester = "john.doe@example.com",
Item = "Vacation Request - 5 days",
TimeoutHours = 24
};
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(ApprovalOrchestration), input);
Console.WriteLine($"Started approval workflow: {instanceId}");
// Simulate human approving the request
Console.WriteLine("Simulating approval...");
await Task.Delay(2000);
// Raise the approval event
var approvalResponse = new ApprovalResponseData
{
IsApproved = true,
Approver = "manager@example.com"
};
await client.RaiseEventAsync(instanceId, "approval_response", approvalResponse);
// Wait for completion
var result = await client.WaitForInstanceCompletionAsync(instanceId, getInputsAndOutputs: true);
Console.WriteLine($"Result: {result.ReadOutputAs<ApprovalResult>().Status}");
Sonraki Adımlar
Bu örnek, WaitForExternalEvent ve CreateTimer API'leri de dahil olmak üzere gelişmiş Dayanıklı İşlevler özelliklerini gösterir.
Task.WhenAny (C#), context.df.Task.any (JavaScript ve TypeScript) veya context.task_any (Python) birleştirerek kişilerin yanıt vermesini bekleyen iş akışları için güvenilir bir zaman aşımı deseni uygulamayı gösterir.
Bu örnek, yapılandırılabilir zaman aşımlarıyla kişilerin yanıt vermesini bekleyen iş akışlarını uygulamak için Dayanıklı Görev SDK'larının nasıl kullanılacağını gösterir. Temel kavramlar:
-
Dış olaylar: Girişi beklemek için kullanma
WaitForExternalEvent -
Dayanıklı zamanlayıcılar: Zaman aşımı gerçekleştirmek için
CreateTimerkullanma -
Yarış görevleri: İlk tamamlanan görevi işlemek için
WhenAny,when_any, veyaanyOfkullanma