Main Page | Class Hierarchy | Class List | File List | Class Members

ServerStub.cs

00001 using System;
00002 using System.Collections;
00003 using System.Collections.Specialized;
00004 using System.Threading;
00005 using Common;
00006 using ProtocolStack;
00007 
00008 namespace Client {
00013         public class ServerStub {
00014                 public delegate void ServerStubCallback(object o);
00015                 public MessageQueue toServerMsgQ;
00016                 public MessageQueue fromServerMsgQ;
00017                 private StackInterface customProtocolStack;
00018                 private Thread processingThread;
00019                 private CallbackList callbackList;
00020                 ClientControl clientControl;
00021 
00022                 public PendingRequestManager pendingRequestManager;
00023 
00024 
00025                 public ServerStub(ClientControl clientControl) {
00026                         try {
00027                                 this.clientControl = clientControl;
00028                                 customProtocolStack = new StackInterface(new ConnectionResetDelegate(clientControl.ResetConnection));
00029                                 pendingRequestManager = new PendingRequestManager(clientControl);
00030                                 toServerMsgQ = customProtocolStack.MessagesToSend;
00031                                 fromServerMsgQ = customProtocolStack.ReceivedMessages;
00032                                 callbackList = new CallbackList();
00033                         } catch (ApplicationException appEx) {
00034                                 throw new ApplicationException("Unable to create Server Proxy interface in Client Library", appEx);
00035                         }
00036                 }
00037 
00038                 public void ResetConnection() {
00039                         Console.WriteLine("### TODO: Server stub specific connection reset code ###");
00040                         customProtocolStack.ResetConnection();
00041                 }
00042 
00046                 public void ServiceReq(HTTPRequest req, Connection client) {
00047                         // register for callback when response arrives
00048                         HTTPResponseHandler handler = new HTTPResponseHandler(req, client, clientControl);
00049                         int callbackRcpt = callbackList.RegisterHandler(handler);
00050                         //int callbackRcpt = callbackList.RegisterCallback(new ServerStubCallback(client.SendResponseCallback));
00051                         // delta encode / compress the request 
00052                         EncodedHTTPRequest encodedReq = new EncodedHTTPRequest(req);
00053                         // form message
00054                         HTTPRequestMessage outgoingMessage = new HTTPRequestMessage(encodedReq, callbackRcpt, null);
00055                         outgoingMessage.Destination = clientControl.settings.ServerID;
00056                         // send to pending request manager
00057                         pendingRequestManager.ServiceRequest(req.URI, outgoingMessage, handler);
00058                         toServerMsgQ.EnqueueBlocking(outgoingMessage);
00059                 }
00060 
00064                 public void Freshen(byte[] CHK, HTTPRequest request, HTTPResponseHandler responseHandler) {
00065                         // do the freshening thing,
00066                         int callback = callbackList.RegisterHandler(responseHandler);
00067                         HTTPRequestMessage reqMsg = new HTTPRequestMessage(new EncodedHTTPRequest(request), callback, CHK);
00068                         reqMsg.Destination = clientControl.settings.ServerID;
00069 //                      Console.WriteLine("> Freshen request issued for {0} (Identical to HTTP Request)", request.URI);
00070 //                      toServerMsgQ.EnqueueBlocking(reqMsg);
00071                         pendingRequestManager.ServiceRequest(request.URI, reqMsg, responseHandler);
00072                 }
00073 
00074                 public void SendCacheIndexMessage(CacheIndexMessage msg) {
00075                         toServerMsgQ.EnqueueBlocking(msg);
00076                         clientControl.msgLog.LogSend("CLIENT CACHE INDEX MESSAGE Sent");
00077                 }
00078 
00082                 public void Start() {
00083                         customProtocolStack.Start();
00084                         if (processingThread == null || !processingThread.IsAlive) {
00085                                 processingThread = new Thread(new ThreadStart(this.run));
00086                                 processingThread.Start();
00087                         }
00088                 }
00089 
00093                 public void Stop() {
00094                         customProtocolStack.Stop();
00095                         if (processingThread != null && processingThread.IsAlive) {
00096                                 processingThread.Abort();
00097                                 processingThread.Join();
00098                         }
00099                 }
00100 
00104                 public void run() {
00105                         Message currentMsg;
00106                         try {
00107                                 while(true) {
00108                                         try {
00109                                                 currentMsg = fromServerMsgQ.DequeueBlocking();
00110                                                 // perform appropriate action based on type of message.
00111                                                 ActionMessage(currentMsg);
00112                                         } catch (ApplicationException appEx) {
00113                                                 Console.Error.WriteLine("*** Error processing incoming message ***\n{0}", appEx);
00114                                         }
00115                                 }
00116                         } catch (ThreadAbortException) {
00117                                 Console.WriteLine("Shuting down 'from server' message queue processing");
00118                         }
00119                 }
00120 
00121                 public void ActionMessage(Message msg) {
00122                         // TODO: Change so it swicthes on msg.GetType, or possibly 'implements' interface type for cache update 
00123                         switch(msg.Type) {
00124                                 case MessageType.NoChange: 
00125                                 case MessageType.HTTPResponse: {
00126                                         IResponseHandler respHandler = (IResponseHandler)callbackList[((IContainsCallback)msg).CallbackReceipt];
00127                                         respHandler.Handle(msg);
00128                                         clientControl.serverStub.pendingRequestManager.HandleRemainingRequests(((HTTPResponseHandler)respHandler).RequestUri, msg, true);
00129                                         break;
00130                                 }
00131                                 case MessageType.CacheUpdateHTTPResponse: {
00132                                         clientControl.clientCacheManager.Handle(msg);
00133                                         clientControl.serverStub.pendingRequestManager.HandleRemainingRequests(((ICacheUpdateMessage)msg).RequestUri, msg, false);
00134                                         break;
00135                                 }
00136                                 case MessageType.CacheUpdateNoChange: {
00137                                         clientControl.clientCacheManager.Handle(msg);
00138                                         clientControl.serverStub.pendingRequestManager.HandleRemainingRequests(((ICacheUpdateMessage)msg).RequestUri, msg, false);
00139                                         break;
00140                                 }
00141                                 case MessageType.CacheIndexRequest: {
00142                                         clientControl.clientCacheManager.Handle(msg);
00143                                         break;
00144                                 }
00145                                 case MessageType.HTTPRequest: {
00146                                         // we should not be receiving requests at the client
00147                                         throw new Exception("Warning! HTTP Request received at client");
00148                                 }
00149                                 case MessageType.Retransmission: {
00150                                         // this type of message should not be here
00151                                         throw new Exception("Warning! Retransmission message made it past the protocol level");
00152                                 }
00153                                 case MessageType.Noop: {
00154                                         break; // do nothing
00155                                 }
00156                                 default: {
00157                                         throw new ApplicationException(String.Format("Unrecognised message of type \"{0}\" in Server Stub receive queue processing", msg.Type));
00158                                 }
00159                         }
00160                 }
00161 
00162         }
00163 
00164         /*************************************************************************/
00165         // on receipt of some message, look up here what we're supposed to call back.
00166         // callback gives an integer receipt, which is used to index into the callbacks on return. 
00167         class CallbackList : ListDictionary {
00171                 Random rand;
00172 
00173                 public CallbackList() {
00174                         rand = new Random();
00175                 }
00176                         
00177                 public int RegisterHandler(IResponseHandler responseHandler) {
00178                         int receipt = rand.Next();
00179                         while (this.Contains(receipt)) {
00180                                 receipt = rand.Next();
00181                         }
00182                         this.Add(receipt, responseHandler);
00183                         return receipt;
00184                 }
00185                 
00186         }
00187 
00188         /*************************************************************************/
00189 }

Generated on Mon May 8 22:07:27 2006 by  doxygen 1.3.9.1