ASP.NET Dashboard

Aug 23, 2007 at 1:56 PM
Hi,
I'm working on a publish/subscribe web application and this looks to be a good infrastructure. You mentioned using this in conjunction with an ASP.NET dashboard. Would you have any example code on its implementation?

Thanks
Coordinator
Aug 26, 2007 at 3:57 AM
I can't post the web application monitoring code but will give you a brief overview.

I have an httpmodule which does time sampling. On the first asp.net request of the page view, I record the start time. As each subsequent request is completed I update the completion time for the page view. When there is a half second of no requests then I consider the page view to be completed and update a counter for that application. So the httpmodule is aggregating all the individuals http requests made when rendering a page.

There is a windows service on the machine that harvests the counters and publish them as events. The monitoring dashboard application sends requests to find out what applications exist and when a user selects to monitor a specific application an event is published to request that application's counters.

The dashboard application aggregates the counters across all the machines running the application. I then use Dundas controls to present an aggregated view of page views / second, errors / second, and average response time. I also show each individual machine running the application and its data as well.

This is a very simplified overview of the application pieces. The event system provides the communication infrastructure that allows the application to scale across a very large web farm and present an aggregated view within a few seconds of what is actually happening to the servers.

Hope this is helpful.

Keith

pvulcan wrote:
Hi,
I'm working on a publish/subscribe web application and this looks to be a good infrastructure. You mentioned using this in conjunction with an ASP.NET dashboard. Would you have any example code on its implementation?

Thanks

Nov 12, 2007 at 1:48 PM
Do have any samples yet for asp.net? I have been trying to get the listner to work on the web, but not having any success. Any samples would be great.

Thanks

keithh wrote:
I can't post the web application monitoring code but will give you a brief overview.

I have an httpmodule which does time sampling. On the first asp.net request of the page view, I record the start time. As each subsequent request is completed I update the completion time for the page view. When there is a half second of no requests then I consider the page view to be completed and update a counter for that application. So the httpmodule is aggregating all the individuals http requests made when rendering a page.

There is a windows service on the machine that harvests the counters and publish them as events. The monitoring dashboard application sends requests to find out what applications exist and when a user selects to monitor a specific application an event is published to request that application's counters.

The dashboard application aggregates the counters across all the machines running the application. I then use Dundas controls to present an aggregated view of page views / second, errors / second, and average response time. I also show each individual machine running the application and its data as well.

This is a very simplified overview of the application pieces. The event system provides the communication infrastructure that allows the application to scale across a very large web farm and present an aggregated view within a few seconds of what is actually happening to the servers.

Hope this is helpful.

Keith

pvulcan wrote:
Hi,
I'm working on a publish/subscribe web application and this looks to be a good infrastructure. You mentioned using this in conjunction with an ASP.NET dashboard. Would you have any example code on its implementation?

Thanks


Coordinator
Nov 12, 2007 at 4:44 PM
You will find some samples in the source code download. Have you created any classes to define your events that you want to communicate with? What behavior do you want to have, uni-directional or bi-directional. For instance, in my application monitoring application, the front-end service subscribes to subscription events to see if anyone has subscribed to the monitoring events. Only if someone subscribes does the service begins publishing monitoring events. This is really a uni-directional paradigm.

The ping pong sample is an example of bi-directional where one service (a windows application) sends an event to a service making a request and the service responds with requested events. In this case, the initial requester dynamically generates an event id (guid), subscribes to that new event id, sends the request event specifying that the response events should be published using the event id. This way, the requestor will be only one who subscribed to the event id and the only one who would receive it.

If you want some help, you need to define your event classes and give an overview of what type of interaction you want between publishers and subscribers.

Keith


pvulcan wrote:
Hi,
I'm working on a publish/subscribe web application and this looks to be a good infrastructure. You mentioned using this in conjunction with an ASP.NET dashboard. Would you have any example code on its implementation?

Thanks

Nov 13, 2007 at 1:15 PM
The Problem
I have many clients application (web or windows) that will consume an asmx web service. The web service will have a method call GetCustomerDataById(34), which would perform the following steps inside the web method call.
1. Validate the incoming request first
2. Generate a Claimcheck ticket
3. Send Claimcheck to a database for looking up later
4. Send Claimcheck stamp with the request to msmq
5. Return Claimcheck to client

This will give me the ability to guarantee that the request was accepted from the web service, and then it return back quickly with a claimcheck number. Then i have a windows service that monitors and moves every message from the inbox queue to the process queue. Then i have another windows service that will read thru every message in the process queue and do the processing for that request. My problem is that how do i notify the web service and the client (asp.net or window forms) that the response is ready and here are the results. What I’m trying to do is to create scaleable web services from the server side and have a more message base communication flow. So now this brings me to your solution (WSP). I guess really what I’m looking for is some eventing system that will let the consumer know that the response is ready and return it back to the original caller or anyone subscribing to that event. I’m still trying to grock on what is an “event” in WSP? I tried to copy the code from your listener example into an asp.net and it’s not returning focus back to the page, it looks like its just hanging.

I guess i'm looking for the behavior like IAsync callback...or bi-directional

Thanks for your help, and btw this framework is really cool


keithh wrote:
You will find some samples in the source code download. Have you created any classes to define your events that you want to communicate with? What behavior do you want to have, uni-directional or bi-directional. For instance, in my application monitoring application, the front-end service subscribes to subscription events to see if anyone has subscribed to the monitoring events. Only if someone subscribes does the service begins publishing monitoring events. This is really a uni-directional paradigm.

The ping pong sample is an example of bi-directional where one service (a windows application) sends an event to a service making a request and the service responds with requested events. In this case, the initial requester dynamically generates an event id (guid), subscribes to that new event id, sends the request event specifying that the response events should be published using the event id. This way, the requestor will be only one who subscribed to the event id and the only one who would receive it.

If you want some help, you need to define your event classes and give an overview of what type of interaction you want between publishers and subscribers.

Keith


pvulcan wrote:
Hi,
I'm working on a publish/subscribe web application and this looks to be a good infrastructure. You mentioned using this in conjunction with an ASP.NET dashboard. Would you have any example code on its implementation?

Thanks


Coordinator
Nov 14, 2007 at 6:26 AM
How many clients/users does the system have?
What is the requests / second?
Is the traffic in a private network or across the internet?
How long and how much time does it take to process the event?

My inclination would be to have a class library over the DB to have a clean abstraction of the data and have the object library go directly to the DB. When you get to large scale, you would place a caching layer between the object library and the DB. An adaptive replacement cache algorithm would probably be what I would implement. It the application updates the DB, I would make it a write-through cache.

Regarding the subscription manager in ASP.Net, it starts up a background thread which actually listens for events. So when your app domain starts up, you would want to start your own background thread and have it start the subscription manager.

With the event system, if you simply wanted to notify a process that data is waiting for it, you could create have the requesting application place a request id (guid) as a property in its request. The service could respond with an event that contained the request id. The requesting application would be listening for events with its request id.

After you answer the questions above, I'll hopefully get a better grasp of the problem you're trying to solve.

Keith
Nov 14, 2007 at 3:39 PM
How many clients/users does the system have?- About 50
What is the requests / second? - about 7sec
Is the traffic in a private network or across the internet? - private network
How long and how much time does it take to process the event? - 15sec

Ok..the trouble I’m having is implementing the subscription manager in asp.net, maybe because I’m not for sure on how to implement it. Can you post an example that illustrates starting a new thread on the page load and waiting for a specific event (request id) to be raised. Once the event is raised I would like to trigger an Ajax event to render the data on the screen. After i get this working I would like to see if it's a viable solution for reliable message handling via web services.

Thanks again for your quick response.


keithh wrote:
How many clients/users does the system have?
What is the requests / second?
Is the traffic in a private network or across the internet?
How long and how much time does it take to process the event?

My inclination would be to have a class library over the DB to have a clean abstraction of the data and have the object library go directly to the DB. When you get to large scale, you would place a caching layer between the object library and the DB. An adaptive replacement cache algorithm would probably be what I would implement. It the application updates the DB, I would make it a write-through cache.

Regarding the subscription manager in ASP.Net, it starts up a background thread which actually listens for events. So when your app domain starts up, you would want to start your own background thread and have it start the subscription manager.

With the event system, if you simply wanted to notify a process that data is waiting for it, you could create have the requesting application place a request id (guid) as a property in its request. The service could respond with an event that contained the request id. The requesting application would be listening for events with its request id.

After you answer the questions above, I'll hopefully get a better grasp of the problem you're trying to solve.

Keith

Coordinator
Nov 15, 2007 at 2:02 AM

I didn't test the code but it would be something like this:

global.asax.cs file:


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace WebApplication1
{
public class Global : System.Web.HttpApplication
{

protected void Application_Start(object sender, EventArgs e)
{
System.Threading.Thread workerThread;
ResponseHandler responseHandler = new ResponseHandler();
workerThread = new System.Threading.Thread(new System.Threading.ThreadStart(responseHandler.Start));
workerThread.Start();
}

protected void Application_End(object sender, EventArgs e)
{

}
}
}


default.aspx.cs file:


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Threading;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.WebSolutionsPlatform.Common;
using Microsoft.WebSolutionsPlatform.Event.PubSubManager;
using Microsoft.WebSolutionsPlatform.Event;

namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
}

public class ResponseEvent : Microsoft.WebSolutionsPlatform.Event.Event
{
private Guid responseId;
/// <summary>
/// ID used for correlation
/// </summary>
public Guid ResponseId
{
get
{
return responseId;
}

set
{
responseId = value;
}
}

/// <summary>
/// Base constructor to create a new event
/// </summary>
public ResponseEvent()
: base()
{
EventType = new Guid(@"ACDAEFBA-7211-4f43-ABFD-2D23FC114D80");
}

/// <summary>
/// Base constructor to create a new event from a serialized event
/// </summary>
/// <param name="serializationData">Serialized event data</param>
public ResponseEvent(byte[] serializationData)
: base(serializationData)
{
}

/// <summary>
/// Used for event serialization.
/// </summary>
/// <param name="data">SerializationData object passed to store serialized object</param>
public override void GetObjectData(SerializationData data)
{
data.AddElement(@"ResponseId", ResponseId);
}
}

public class ResponseHandler : ISubscriptionCallback
{
private static SubscriptionManager.Callback subCallback;
private static SubscriptionManager subMgr;

public void Start()
{
try
{
ResponseEvent responseEvent = new ResponseEvent();

subCallback = new SubscriptionManager.Callback(SubscriptionCallback);
subMgr = new SubscriptionManager(subCallback);
subMgr.AddSubscription(responseEvent.EventType, false);
subMgr.ListenForEvents = true;

Thread.Sleep(Timeout.Infinite);
}
catch
{
}
finally
{
if (subMgr != null)
{
subMgr.ListenForEvents = false;
}
}
}

public void SubscriptionCallback(Guid eventType, byte[] serializedEvent)
{
ResponseEvent responseEvent = new ResponseEvent(serializedEvent);

// Do lookup and notify application
}
}
}
Nov 15, 2007 at 3:52 PM
HERE IS MY PUBLISHING CLASS THIS IS IN A CONSOLE APPLICATION

using Entities;
using DataLayer;
using System.Messaging;
using System.Data.SqlClient;
using Microsoft.WebSolutionsPlatform.Event.PubSubManager;
using Microsoft.WebSolutionsPlatform.Event;
public class Processor
{
private PublishManager pubMgr;

public object GetClaimChecks()
{
//Step1 Get claim check from database
SqlConnection Connection = new SqlConnection("Data Source=.\\sqlexpress;Initial Catalog=C:\\PROGRAM FILES\\MICROSOFT SQL SERVER\\MSSQL.4\\MSSQL\\DATA\\asdfasdf Security=True");
SqlCommand Command = new SqlCommand();


try {
Connection.Open();
{
Command.Connection = Connection;
Command.CommandText = "GetClaimChecks";
Command.CommandType = CommandType.StoredProcedure;

SqlDataReader dr = Command.ExecuteReader();

dr.Read();

if (dr.HasRows == true) {
GetClaimCheckFromQueue((string)dr("ProcessQueueClaimCheck"));
}
}

Connection.Close();
}
catch (Exception ex) {
Connection.Close();
Connection.Dispose();
Command.Dispose();
}

Connection.Dispose();
Command.Dispose();


}

private void GetClaimCheckFromQueue(string ClaimCheck)
{
//Step2 Get msg from the process queue using the claim checkid
MessageQueue q;
Messaging.Message m;
CustomerRequest Request = new CustomerRequest();
string i;
string x;
string type;



if (MessageQueue.Exists("crp-031533-capl\\Processing")) {
q = new MessageQueue("crp-031533-capl\\Processing");
}
else {
q = MessageQueue.Create("crp-031533-capl\\Processing");
}

try {
m = q.PeekById(ClaimCheck);

switch (m.Label) {
case "CustomerbyVicCard":
q.Formatter = new XmlMessageFormatter(new Type[] {typeof(CustomerRequest)});
m = q.PeekById(ClaimCheck);
Request = (CustomerRequest)m.Body;

VicCustomerData GetData = new VicCustomerData();

//Step3 Call data access code and pass in the msg
CustomerResponse Response = new CustomerResponse();

//Get Data and populate the Event response class
Response = GetData.GetCustomerbyVicCardData(Request);
Response.CustomerId = ClaimCheck;

//Step4 publish data back to the subscribers
pubMgr = new PublishManager();
pubMgr.Publish(Response.Serialize());
break;

case "CustomerRequest2":
break;
case "CustomerRequestq":
break;
case "CustomerRequest4":
break;
case "CustomerRequest3":
break;


}
}


catch (Exception ex) {
x = "(no message)";
}

}




}



Here is my event that I created, this event resides in it own class library called entities

using Microsoft.WebSolutionsPlatform.Event;
public class CustomerResponse : Event
{

private string _CustomerId;
public string CustomerFirstName;
public string CustomerLastName;
public string CustomerVicCardId;
public string CustomerAddress;
public string CustomerCity;
public string CustomerZip;
public string CustomerState;
public DateTime CustomerDOB;
public bool CustomerEVIC;

public CustomerResponse() : base()
{
EventType = new Guid("24923A0F-04CB-4dcb-8EA9-3D1CAA316B23");
}

public CustomerResponse(byte[] serializationData) : base(serializationData)
{
}

public string CustomerId {
get { return _CustomerId; }
set { _CustomerId = value; }
}

public override void GetObjectData(Microsoft.WebSolutionsPlatform.Event.SerializationData data)
{
data.AddElement("Customerid", CustomerId);
}

}



Here is my Subscriber web page that will listen for all events, this web page is referencing the CustomerResponse Event class that was created. The problem is…the subscriber event gets fired when I publish the event but it showing the event has empty. The customerid is not poplulated for some reason. I’m trying to get the data that I published. Sorry for so many questions, but I would really like for this to work.

using System;
using Entities;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Microsoft.WebSolutionsPlatform.Event;
using Microsoft.WebSolutionsPlatform.Event.PubSubManager;

public partial class WebForm1 : System.Web.UI.Page, ISubscriptionCallback
{

private SubscriptionManager subMgr;
private SubscriptionManager.Callback subCallback;
public static object obj;
public static int numIterations;
static DateTime startTime;
public delegate void Run_Delegate();
public static CustomerResponse Data = new CustomerResponse();


protected void Page_Load(object sender, System.EventArgs e)
{
if (Page.IsPostBack == false) {
Runtest();
}
}

private void Runtest()
{
Run_Delegate d;
d = new Run_Delegate(Run);

TimeSpan totalTime;
try {
IAsyncResult R;
R = d.BeginInvoke(null, new AsyncCallback(TaskCompleted));
Response.Write(totalTime.TotalSeconds);
}
catch (Exception ex) {
Response.Write(ex.Message);
}


}

private void Run()
{

try {
subCallback = new SubscriptionManager.Callback(SubscriptionCallback);
subMgr = new SubscriptionManager(subCallback);
subMgr.AddSubscription(Guid.Empty, false);
}


catch (Exception ex) {
Response.Write(ex.Message);
}
finally {
//subMgr.RemoveSubscription(Guid.Empty)

//subMgr.ListenForEvents = False

//Thread.CurrentThread.Abort()
}
}

public void Microsoft.WebSolutionsPlatform.Event.PubSubManager.ISubscriptionCallback.SubscriptionCallback(System.Guid eventType, byte[] serializedEvent)
{
CustomerResponse localEvent = new CustomerResponse();
localEvent = new CustomerResponse(serializedEvent);

string info;


info = localEvent.CustomerId;

if (info == "09c3f298-4409-4e86-a077-f363a316bcf1\\4111") {
Data = localEvent;
}


return;
}

public void TaskCompleted(IAsyncResult R)
{
// Write here code to handle the completion of
// your asynchronous method
}

protected void Button1_Click(object sender, System.EventArgs e)
{
this.TextBox1.Text = "hello";
}

protected void Timer1_Tick(object sender, System.EventArgs e)
{
TextBox1.Text = Data.EventName.ToString;
}



}
Nov 15, 2007 at 7:02 PM
I got it working now i didnt add anything to the GetObjectData method...the data.addelements stuff

Thanks
Coordinator
Nov 15, 2007 at 8:06 PM
You should also move the creation of the PublishMgr object to where you declare it. It looks like you're creating a new PublishMgr instance for each time you publish. And I see you caught that you needed to add all the elements in the GetObjectData method.

Keith