예제 #1
0
        private static void RegisterNeighbourContext(HttpListenerContext http_ctx)
        {
            Guid otherGuid; string otherHostname; int otherPort;
            using (var bodyReader = new StreamReader(http_ctx.Request.InputStream, http_ctx.Request.ContentEncoding ?? Encoding.ASCII))
            {
                otherGuid = Guid.Parse(bodyReader.ReadLine());
                otherHostname = bodyReader.ReadLine();
                otherPort = int.Parse(bodyReader.ReadLine());
            }

            if (nodeGuid.CompareTo(otherGuid) < 0)
                outgoingNodeConnections[otherGuid] = new NetworkNode { Hostname = otherHostname, Port = otherPort };
            else
                incomingNodeConnections[otherGuid] = new NetworkNode { Hostname = otherHostname, Port = otherPort };

            var respBodyString = GetNodeSpecString(http_ctx);
            var repsBodyData = Encoding.ASCII.GetBytes(respBodyString);
            http_ctx.Response.StatusCode = (int)HttpStatusCode.OK;
            http_ctx.Response.ContentType = MediaTypeNames.Text.Plain;
            http_ctx.Response.ContentEncoding = Encoding.ASCII;
            http_ctx.Response.Close(repsBodyData, willBlock: false);
        }
예제 #2
0
        private static async Task ExchangeWithNode(Uri otherNodeUri, byte[] nodeSpecData, string contentType)
        {
            var req = WebRequest.Create(new Uri(otherNodeUri, "/registerNeighbour")) as HttpWebRequest;
            req.Method = WebRequestMethods.Http.Post;
            req.ContentType = contentType;
            req.ContentLength = nodeSpecData.Length;
            using (var reqStream = await req.GetRequestStreamAsync())
            {
                await reqStream.WriteAsync(nodeSpecData, 0, nodeSpecData.Length);
                await reqStream.FlushAsync();
            }

            Guid otherGuid; string otherHostname; int otherPort;
            using (var resp = await req.GetResponseAsync() as HttpWebResponse)
            {
                var respEncoding = string.IsNullOrWhiteSpace(resp.ContentEncoding) ? Encoding.ASCII : Encoding.GetEncoding(resp.ContentEncoding);
                using (var respReader = new StreamReader(resp.GetResponseStream(), respEncoding))
                {
                    otherGuid = Guid.Parse(await respReader.ReadLineAsync());
                    otherHostname = await respReader.ReadLineAsync();
                    otherPort = int.Parse(await respReader.ReadLineAsync());
                }

            }

            if (nodeGuid.CompareTo(otherGuid) < 0)
                outgoingNodeConnections[otherGuid] = new NetworkNode { Hostname = otherHostname, Port = otherPort };
            else
                incomingNodeConnections[otherGuid] = new NetworkNode { Hostname = otherHostname, Port = otherPort };
        }
예제 #3
0
 private static Task SendLeaderElectionResponse(LeaderElectionState electionState, NetworkNode nodeTuple, bool responseState, bool uniqueState, bool uselessState)
 {
     var uriBuilder = new UriBuilder(Uri.UriSchemeHttp, nodeTuple.Hostname, nodeTuple.Port, "/secondYo/Response");
     var reqDataString = string.Join(Environment.NewLine, 
         electionState.Guid, electionState.CreationTime.ToString("o"), nodeGuid, responseState, uniqueState, uselessState);
     var reqDataBytes = Encoding.ASCII.GetBytes(reqDataString);
     return SendNotificationPostRequestToNode(uriBuilder.Uri, reqDataBytes);
 }
예제 #4
0
 private static Task SendLeaderElectionAdvertisement(LeaderElectionState electionState, NetworkNode nodeTuple, Guid advertGuid)
 {
     var uriBuilder = new UriBuilder(Uri.UriSchemeHttp, nodeTuple.Hostname, nodeTuple.Port, "/firstYo/Advertise");
     var reqDataString = string.Join(Environment.NewLine, electionState.Guid, electionState.CreationTime.ToString("o"), nodeGuid, advertGuid);
     var reqDataBytes = Encoding.ASCII.GetBytes(reqDataString);
     return SendNotificationPostRequestToNode(uriBuilder.Uri, reqDataBytes);
 }
예제 #5
0
 private static async Task SendSecondYoFlipNode(NetworkNode nodeTuple)
 {
     var uriBuilder = new UriBuilder(Uri.UriSchemeHttp, nodeTuple.Hostname, nodeTuple.Port, "/secondYo/Flip");
     var req = WebRequest.Create(uriBuilder.Uri) as HttpWebRequest;
     req.Method = WebRequestMethods.Http.Post;
     req.ContentType = new ContentType(MediaTypeNames.Text.Plain) { CharSet = Encoding.ASCII.WebName }.ToString();
     var reqDataString = nodeGuid.ToString() + Environment.NewLine;
     var reqDataBytes = Encoding.ASCII.GetBytes(reqDataString);
     req.ContentLength = reqDataBytes.LongLength;
     try
     {
         using (var reqStream = await req.GetRequestStreamAsync())
         {
             await reqStream.WriteAsync(reqDataBytes, 0, reqDataBytes.Length);
             await reqStream.FlushAsync();
         }
         using (var resp = await req.GetResponseAsync()) { }
     }
     catch (WebException) { }
 }
예제 #6
0
        private static async void HandleHttpContext(HttpListener http_listener)
        {
            HttpListenerContext http_ctx;
            try { http_ctx = await http_listener.GetContextAsync(); }
            catch (Exception) { return; }

            //nodeStateLock.EnterReadLock();

            try
            {
                HandleHttpContext(http_listener);

                var path = http_ctx.Request.Url.AbsolutePath;
                if (string.Equals("/getCurrentLeader", path, StringComparison.OrdinalIgnoreCase))
                {
                    var inNodeKvps = incomingNodeConnections.ToArray();
                    var outNodeKvps = outgoingNodeConnections.ToArray();

                    var newElectionState = new LeaderElectionState(inNodeKvps.Where(kvp => !kvp.Value.IsUselessConnection).Select(kvp => kvp.Key),
                            outNodeKvps.Where(kvp => !kvp.Value.IsUselessConnection).Select(kvp => kvp.Key))
                    { Guid = Guid.NewGuid(), CreationTime = DateTime.Now, FirstYoMinimum = nodeGuid };

                    leaderElections[newElectionState.Guid] = newElectionState;

                    SendLeaderElectionAdvertisementRequest(newElectionState, new NetworkNode { Hostname = "localhost", Port = portNumber }).Wait();

                    Guid? currentLeader;
                    do
                    {
                        Task.Delay(42).Wait();
                        currentLeader = leaderGuid;
                    } while (currentLeader == null);

                    NetworkNode leaderNode;
                    if (currentLeader == nodeGuid)
                        leaderNode = new NetworkNode { Hostname = http_ctx.Request.LocalEndPoint.Address.ToString(), Port = portNumber };
                    else if (!incomingNodeConnections.TryGetValue(currentLeader.GetValueOrDefault(), out leaderNode))
                    {
                        http_ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        http_ctx.Response.Close();
                    }

                    http_ctx.Response.ContentType = MediaTypeNames.Text.Plain;
                    http_ctx.Response.ContentEncoding = Encoding.ASCII;
                    http_ctx.Response.StatusCode = (int)HttpStatusCode.OK;
                    http_ctx.Response.Close(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", leaderNode.Hostname, leaderNode.Port)), willBlock: false);
                }
                else if (string.Equals("/getNodes", path, StringComparison.OrdinalIgnoreCase))
                {
                    GetNodesContext(http_ctx);
                }
                else if (string.Equals("/getNodesWithGuids", path, StringComparison.OrdinalIgnoreCase))
                {
                    GetNodesContext(http_ctx, withGuids: true);
                }
                else if (string.Equals("/getGuid", path, StringComparison.OrdinalIgnoreCase))
                {
                    GetGuidContext(http_ctx);
                }
                else if (string.Equals("/connectToNodes", path, StringComparison.OrdinalIgnoreCase))
                {
                    await ConnectToNodesContext(http_ctx);
                }
                else if (string.Equals("/registerNeighbour", path, StringComparison.OrdinalIgnoreCase))
                {
                    RegisterNeighbourContext(http_ctx);
                }
                else if (string.Equals("/clearConnections", path, StringComparison.OrdinalIgnoreCase))
                {
                    ClearConnectionsContext(http_ctx);
                }
                else if (string.Equals("/deregisterNode", path, StringComparison.OrdinalIgnoreCase))
                {
                    await DeregisterNodeContext(http_ctx);
                }
                else if (string.Equals("/firstYo/Advertise", path, StringComparison.OrdinalIgnoreCase))
                {
                    FirstYoAdvertisementContext(http_ctx);
                }
                else if (string.Equals("/firstYo/RequestAdvertisement", path, StringComparison.OrdinalIgnoreCase))
                {
                    FirstYoRequestAdvertisementContext(http_ctx);
                }
                else if (string.Equals("/secondYo/Response", path, StringComparison.OrdinalIgnoreCase))
                {
                    SecondYoResponseContext(http_ctx);
                }
                else if (string.Equals("/secondYo/Flip", path, StringComparison.OrdinalIgnoreCase))
                {
                    SecondYoFlipContext(http_ctx);
                }
                else
                {
                    http_ctx.Response.ContentType = MediaTypeNames.Text.Plain;
                    http_ctx.Response.ContentEncoding = Encoding.ASCII;
                    http_ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    http_ctx.Response.Close(Encoding.ASCII.GetBytes("The requested resource could not be found."), willBlock: false);
                }
            }
            finally
            {
                //nodeStateLock.ExitReadLock();
            }
        }