Elsa Core
Elsa Core 之 SendSignal
流程设计器中定义
使用依赖注入
public class FireController : Controller
{
private readonly ISignaler _signaler;
public FireController(ISignaler signaler)
{
_signaler = signaler;
}
[HttpGet("start")]
public async Task<IActionResult> StartFire(CancellationToken cancellationToken)
{
var startedWorkflows = await _signaler.TriggerSignalAsync("Fire", cancellationToken: cancellationToken);
return Ok(startedWorkflows);
}
[HttpGet("{workflowInstanceId}/extinguish")]
public async Task<IActionResult> Extinguish(string workflowInstanceId, CancellationToken cancellationToken)
{
var startedWorkflows = await _signaler.TriggerSignalAsync("Water", workflowInstanceId: workflowInstanceId, cancellationToken: cancellationToken);
return Ok(startedWorkflows);
}
}
ISignaler
注:注意参数 correlationId
public interface ISignaler
{
/// <summary>
/// Runs all workflows that start with or are blocked on the <see cref="SignalReceived"/> activity.
/// </summary>
Task<IEnumerable<CollectedWorkflow>> TriggerSignalTokenAsync(string signalToken, object? input = default, CancellationToken cancellationToken = default);
/// <summary>
/// Runs all workflows that start with or are blocked on the <see cref="SignalReceived"/> activity.
/// </summary>
Task<IEnumerable<CollectedWorkflow>> TriggerSignalAsync(string signal, object? input = null, string? workflowInstanceId = null, string? correlationId = null, CancellationToken cancellationToken = default);
/// <summary>
/// Dispatches all workflows that start with or are blocked on the <see cref="SignalReceived"/> activity.
/// </summary>
Task<IEnumerable<CollectedWorkflow>> DispatchSignalTokenAsync(string token, object? input = default, CancellationToken cancellationToken = default);
/// <summary>
/// Dispatches all workflows that start with or are blocked on the <see cref="SignalReceived"/> activity.
/// </summary>
Task<IEnumerable<CollectedWorkflow>> DispatchSignalAsync(string signal, object? input = default, string? workflowInstanceId = default, string? correlationId = default, CancellationToken cancellationToken = default);
}
通过调用http触发
代码实现过程
1、创建token
public static string GenerateSignalUrl(this ActivityExecutionContext context, string signal)
{
var token = context.GenerateSignalToken(signal);
var url = $"/signals/trigger/{token}";
var absoluteUrlProvider = context.GetService<IAbsoluteUrlProvider>();
return absoluteUrlProvider.ToAbsoluteUrl(url).ToString();
}
2、接收触发
[ApiController]
[Route("signals/trigger/{token}")]
[Produces("application/json")]
public class TriggerEndpoint : ControllerBase
{
private readonly ISignaler _signaler;
private readonly ITokenService _tokenService;
private readonly IMediator _mediator;
public TriggerEndpoint(ISignaler signaler, ITokenService tokenService, IMediator mediator)
{
_signaler = signaler;
_tokenService = tokenService;
_mediator = mediator;
}
[HttpGet, HttpPost]
public async Task<IActionResult> Handle(string token, CancellationToken cancellationToken)
{
if (!_tokenService.TryDecryptToken(token, out SignalModel signal))
return BadRequest();
var affectedWorkflows = await _signaler.TriggerSignalAsync(signal.Name, null, signal.WorkflowInstanceId, cancellationToken: cancellationToken).ToList();
await _mediator.Publish(new HttpTriggeredSignal(signal, affectedWorkflows), cancellationToken);
var response = HttpContext.Response;
return response.HasStarted || response.StatusCode != (int) HttpStatusCode.OK
? new EmptyResult()
: Ok(affectedWorkflows);
}
}
触发过程
Url形如
https://localhost:5001/signals/trigger/CfDJ8N8Lsy4pruVEidtlAk3o7Q8ldA99wFAiqleV276DAD7X0sKGxxsBtKpIK6QUwOHx9d-Rz8T3xJwAd-VAx7vlzLszj-hZb2VVsFOjUrrd73yNiRo4509LFMf0LaReXev3VWM9qoiKrXfcncwMkPaJUAu0qyYiPSGC1YaLF0N16YvG3EFYxiIuO2nH38oVNhxgLsw27s5S1Xg3q-1zU3K67Hw
上面的链接
使用设计器
可以参考如下代码
Document from {{ Variables.Document.Author.Name }} received for review.<br><a href="{{ "Approve" | signal_url }}">Approve</a> or <a href="{{ "Reject" | signal_url }}">Reject</a>
上面的signal_url 是一个filter,通过该filter看可以生成上面的Url
关键字: elsa