/// <summary> /// Connect the Client to the given host server. /// </summary> public bool Connect() { //Set the internal tcpClient object tcpClient = new TcpClient(); //tcpClient.NoDelay = true; // again.. for nagles... and its entirely too much to explain. try { //we leave the Client connection synchronous, to avoid timing issue with writes tcpClient.Connect(serverEndpoint); //get the network stream NetworkStream nStream = tcpClient.GetStream(); //asynchronously read data ClientState state = new ClientState(tcpClient); nStream.BeginRead(state.Buffer, 0, state.Buffer.Length, readCallback, state); return true; } catch (Exception e) { //there was a problem connecting Log.Error(e.ToString()); return false; } }
/// <summary> /// A verification response has been returned. /// </summary> /// <param id="state">The state object of the response.</param> private void verificationResponse(ClientState state) { SerializationEngine serializer = new SerializationEngine (); Verification vResponse = (Verification)serializer.Deserialize(state.GetDataArray()); NodeID = vResponse.NodeID; HostName = vResponse.HostName; DPI = vResponse.DPI; CPUCount = vResponse.CPUCount; RunningJobs = vResponse.JobCount; TotalMemory = vResponse.TotalMemory; //make sure the assembly and domain listing is good foreach (string assembly in loadedAssemblies) { if(!loadedAssemblies.Contains(assembly)){ loadedAssemblies.Add(assembly); } } foreach (string domain in loadedDomains) { if (!loadedDomains.Contains(domain)) { loadedDomains.Add(domain); } } }
//----------------------Response Functions-----------------------// /// <summary> /// The sent message is of unknown type. /// </summary> /// <param id="state">The state object of the response.</param> private void unknowMessageType(ClientState state) { //TODO: handle unknown message type }
/// <summary> /// A distributed job has completed succesfully and this is the response. /// </summary> /// <param id="state">The state object of the response.</param> private void returnExecution(ClientState state) { SerializationEngine serializer = new SerializationEngine (); ExecutionResult res = (ExecutionResult)serializer.Deserialize(state.GetDataArray()); DomainManager.ReturnExecution(res); }
/// <summary> /// Called when a denied execution response is sent. /// </summary> /// <param id="state">The state object of the response.</param> private void deniedExecution(ClientState state) { //TODO: handle denied execution. }
/// <summary> /// called when an assembly load message is returned /// </summary> /// <param id="state">The state object of the response.</param> private void assemblyLoaded(ClientState state) { assemblyLoadReset.Set(); }
/// <summary> /// Callback fired after a read operation completed on the socket /// </summary> /// <param name="result">The result of the read.</param> private void readCallback(IAsyncResult result) { //Who wrote this method? I'm not claiming it... nope. int read = 0; NetworkStream nStream = null; try { //get the network stream nStream = tcpClient.GetStream(); //end the read read = nStream.EndRead(result); } catch (ObjectDisposedException e) { Log.Error(e.ToString()); //if the Client has been disposed, we set read to 0 to allow cleanup of the TCPClient read = 0; } catch (System.IO.IOException e) { //the client got disconnected, that is fine, we simply need to re open with the reconnect, that will happen with the verify interval Log.Warning("Client: '" + tcpClient.Client.AddressFamily.ToString() + "' disconnected! Exception: " + e.ToString()); read = 0; } //get the server state object ClientState state = (ClientState)result.AsyncState; if (read > 0) { state.PurgeBuffer(read); //check if the message is fully recieved, if it is, create a new state object and pass that to the read, // if not, continue the read with the same state object if (state.IsFullyRecieved()) { //need to redo all this below.. nto as efficient as I'd like ClientState newState = new ClientState(state.Client); byte[] excessData = state.CompleteAndTrim(); dispatch(state); newState.PreSetData(excessData); bool moreToProcess = newState.IsFullyRecieved(); if (moreToProcess) { do { //this is a terrible terrible process and needs to be rewritten. ClientState newStateRepeat = new ClientState(state.Client); newStateRepeat.PreSetData(excessData); excessData = newStateRepeat.CompleteAndTrim(); dispatch(newStateRepeat); newState.PreSetData(excessData); } while (newState.IsFullyRecieved()); nStream.BeginRead(newState.Buffer, 0, ClientState.BufferSize, readCallback, newState); } else { nStream.BeginRead(newState.Buffer, 0, ClientState.BufferSize, readCallback, newState); } } else { nStream.BeginRead(state.Buffer, 0, ClientState.BufferSize, readCallback, state); } } else { //socket has been closed... handle it //TODO: handle socket close } }
/// <summary> /// Dispatches the recieved message to the appropriate object /// </summary> /// <param name="state">The state object to be dispatched.</param> private void dispatch(ClientState state) { //first extract the message type from the message string messageType = state.GetMessageType(); //if messageType is null we return the Unknowm message response if (messageType == null) { Write(MessageType.UNKOWN); } //find the corresponding message type in the listing and dispatch accordingly, or return Unknown message response if (dispatchList.ContainsKey(messageType)) { dispatchList[messageType].BeginInvoke(state, null, null); } else { Write(MessageType.UNKOWN); } }