さて、前回 id:waritohutsu:20130320:1363768020 はスケジューラの簡単な TIPS を紹介させて頂いたが、それなりに制限が多いと感じる人も居たのではと考えている。この場合、次に考えるのが「スケジューラから何らかの方法でリクエストを飛ばし、他のサービス(Web Site、Cloud Service 等)に処理を移譲できないか…」だと思われる。これらの大まかな処理の流れは以下の図となる。
今回は、上記の図に記載された処理を実際に実現してみる。
1.スケジューラのスクリプト
まずはスケジューラのスクリプトを作成する。コードの詳細な解説は不要だと思うが、HTTPリクエストの送付に(おそらくモバイルサービス特有か?)モジュールとして require('request')を利用して処理を行っている点に注意していほしい。
function mycronjob() { warmUpSite("http://timertest.azurewebsites.net/api/values"); callwebsite("http://timertest.azurewebsites.net/api/values"); } function warmUpSite(url) { console.info("warming up: " + url); var req = require('request'); req.get({ url: url }, function(error, response, body) { if (!error) { console.info("hot hot hot! " + url); } else { console.error('error warming up ' + url + ': ' + error); } }); } function callwebsite(url) { console.info("Executing job: callwebsite"); var req = require('request'); req.post({ headers: { 'Content-Type': 'application/json' }, url: url, body: JSON.stringify({ param1: "卑猥でありたい at " + new Date().toGMTString() }) }, function(error, result, body) { console.info("Job executed executed."); }); }
2. ASP.NET Web API + 3.ロジックで色々と処理
Webサイト側の処理を作成するため、Webサイトを一つ予め作成(今回の例では http://timertest.azurewebsites.net)しておく必要がある。以下に、Webサイト上で稼働させる Web API 側の処理を記載する。処理内容は、GET/POSTのリクエストが届いた場合にカウンタをカウントアップし、POSTのリクエストが届いた場合はパラメータを格納している程度だ。
- ValuesController.cs
using System.Collections.Generic; using System.Web.Http; using MvcApp.Models; namespace MvcApp.Controllers { public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { GlobalModel.Count++; return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]ParamModel model) { GlobalModel.Count++; GlobalModel.Parametors.Add(model.Param1); } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } } }
上記のコードで利用しているモデルクラスはそれぞれ以下となる。
- GlobalModel.cs
using System.Collections.Generic; namespace MvcApp.Models { public static class GlobalModel { static private List<string> _parametors = new List<string>(); static public long Count { get; set; } static public IList<string> Parametors { get { return _parametors; } } } }
- ParamModel.cs
namespace MvcApp.Models { public class ParamModel { public string Param1 { get; set; } } }
最後に、格納結果を表示するための画面とコントローラのロジックを記載する。
- Index.cshml
<div id="body"> <section class="featured"> <div class="content-wrapper"> <hgroup class="title"> <h1>Welcome to ASP.NET Web API!</h1> <br /> <h2>@ViewBag.Message</h2> </hgroup> </div> </section> <section class="content-wrapper main-content clear-fix"> <h3>リクエストパラメータとして取得した値 @MvcApp.Models.GlobalModel.Parametors.Count 個</h3> @if (MvcApp.Models.GlobalModel.Parametors.Count == 0) { <div>まだパラメータを受け取ってません</div> } else { <ol class="round"> @foreach (var str in MvcApp.Models.GlobalModel.Parametors) { <li>@str</li> } </ol> } </section> </div>
- HomeController.cs
using System.Web.Mvc; using MvcApp.Models; namespace MvcApp.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "GET/POSTで呼び出された回数は " + GlobalModel.Count + " 回です"; return View(); } } }
上記の ASP.NET MVC アプリケーションを作成し、作成した Webサイト(今回の例では http://timertest.azurewebsites.net/ )にデプロイする。