/// <summary> /// Invoked on receipt of a response from the other side. /// </summary> /// <param name="pack">Package detailing response data.</param> protected virtual void OnInternalResponseReceived(Package pack) { /* Getting unmatching requests might not be a bad thing all the time. * For example, requests might time out quickly and the responses might arrive later. * If this is the case, the package must simply be ignored. * * But in debug mode, this event will be signaled. * Timeouts should be a sign that something wrong happened. * Wrong things shouldn't happen. * Things that shouldn't happen should be debugged. */ bool res; if (pack.Header.Type == PackageType.InternalResponse) res = PendingInternalRequests.DeclareResponse(pack.Header.IDTop, pack.Payload); else res = PendingRequests.DeclareResponse(pack.Header.IDTop, pack.Payload); if (res) { // All good. } #if DEBUG else { System.Diagnostics.Debug.WriteLine(string.Format("Got bogus response of id {0} and type {1}. Request might have timed out?", pack.Header.IDTop, pack.Header.IDBottom)); } #endif }
/// <summary> /// Invoked when receiving any package from the other side. /// </summary> /// <param name="pack">Package received.</param> protected virtual void OnInternalPackageReceived(Package pack) { switch (pack.Header.Type) { case PackageType.Request: case PackageType.InternalRequest: OnInternalRequestReceived(pack); break; case PackageType.Response: case PackageType.InternalResponse: OnInternalResponseReceived(pack); break; case PackageType.Data: OnDataReceived(new DataReceivedEventArgs(pack.Payload, pack.Header.ID)); break; case PackageType.HeartbeatRequest: OnInternalHeartbeatRequestReceived(pack); break; case PackageType.HeartbeatResponse: OnInternalHeartbeatResponseReceived(pack); break; case PackageType.PeerConnected: OnInternalPeerConnectedReceived(pack); break; case PackageType.PeerDisconnected: OnInternalPeerDisconnectedReceived(pack); break; } }
/// <summary> /// Invoked on successful sending of a request to the other side. /// </summary> /// <param name="pack">Package detailing request data.</param> protected virtual void OnInternalRequestSent(Package pack) { if (pack.Header.Type == PackageType.InternalRequest) PendingInternalRequests.Add(pack.State as Request); else PendingRequests.Add(pack.State as Request); }
private void OnInternalPeerDisconnectedReceived(Package pack) { if (SERVER) { _CheckIfStopped(new InvalidOperationException("Server should not receive this package."), true); } else { lock (_peers_lock) if (_peers == null) _peers_queued_temp.Remove(pack.Header.ID); else if (_peers.Remove(pack.Header.ID)) OnPeerDisconnected(new PeerChangeEventArgs(pack.Header.ID, false)); } }
/// <summary> /// Invoked when successfully sending any package to the other side. /// </summary> /// <param name="pack">Package sent.</param> protected virtual void OnInternalPackageSent(Package pack) { switch (pack.Header.Type) { case PackageType.Request: case PackageType.InternalRequest: OnInternalRequestSent(pack); break; case PackageType.Response: case PackageType.InternalResponse: OnInternalResponseSent(pack); break; } }
private void _OnPipeFailure(Exception x, bool outg, Package pack) { try {//*/ OnPipeFailure(new PipeFailureEventArgs(x, outg)); } finally { if (outg) { switch (pack.Header.Type) { case PackageType.Request: case PackageType.InternalRequest: OnInternalRequestSendFailed(pack, x); break; case PackageType.Response: case PackageType.InternalResponse: OnInternalResponseSendFailed(pack, x); break; case PackageType.HeartbeatRequest: //case PackageType.HeartbeatResponse: OnInternalHeartbeatFailure(pack, x); break; } } else if (pack != null) { switch (pack.Header.Type) { case PackageType.Response: OnInternalResponseReceiveFailed(pack, x); break; } } }//*/ _CheckIfStopped(x); }
/// <summary> /// Invoked on receipt of a request from the other side. /// </summary> /// <param name="pack">Package detailing request data.</param> protected virtual void OnInternalRequestReceived(Package pack) { var res = new Response(this, pack.Header.IDTop, pack.Header.IDBottom, pack.Payload, new TimeSpan(0, 0, 0, 0, pack.Header.RequestTimeout * 10), DateTime.Now) { isInternal = pack.Header.Type == PackageType.InternalRequest }; if (pack.Header.Type == PackageType.InternalRequest) { PendingInternalResponses.Add(res); var e = new RequestReceivedEventArgs(res); InternalRequestHandlers.ExecuteHandler(pack.Header.IDBottom, this, e); } else { PendingResponses.Add(res); var e = new RequestReceivedEventArgs(res); OnRequestReceived(e); RequestHandlers.ExecuteHandler(pack.Header.IDBottom, this, e); } }
/// <summary> /// Invoked when a heartbeat-related failure occurred. /// </summary> /// <param name="pack">Package detailing heartbeat data, if available.</param> /// <param name="x">Exception causing the failure.</param> protected virtual void OnInternalHeartbeatFailure(Package pack, Exception x) { __scoreHeartbeatFailure(); }
/// <summary> /// Invoked on receipt of heartbeat response from the other side. /// </summary> /// <param name="pack">Package detailing heartbeat data.</param> protected virtual void OnInternalHeartbeatResponseReceived(Package pack) { bool awaiting = false; lock (heartbeat_sync) awaiting = awaitingHeartbeat; if (awaiting) { if (pack.Header.ID == lastIDsent) __scoreHeartbeatSuccess(); //else // Shouldn't really happen, but meh. Don't risk it. // __scoreHeartbeatFailure(); // Well. Old timeout packages might arrive very late due to weird pings. They must simply be ignored. } }
/* The methods that handle heartbeat-specific pipe events. */ /// <summary> /// Invoked on receipt of heartbeat request from the other side. /// </summary> /// <param name="pack">Package detailing heartbeat data.</param> protected virtual void OnInternalHeartbeatRequestReceived(Package pack) { try { LowSendPackage(new Packages.PackageHeader() { Type = PackageType.HeartbeatResponse, ID = pack.Header.ID }, emptyPayload); } catch (ObjectDisposedException) { // Do nothing. } catch (Exception x) { _CheckIfStopped(x); } }
/// <summary> /// Invoked on successful sending of a response to the other side. /// </summary> /// <param name="pack">Package detailing response data.</param> protected virtual void OnInternalResponseSent(Package pack) { bool res; if (pack.Header.Type == PackageType.InternalResponse) res = PendingInternalResponses.DeclareSent(pack.Header.IDTop); else res = PendingResponses.DeclareSent(pack.Header.IDTop); if (res) { // yay? } #if DEBUG else { System.Diagnostics.Debug.WriteLine(string.Format("Sent bogus response of id {0} and type {1}. Shouldn't happen...", pack.Header.IDTop, pack.Header.IDBottom)); } #endif }
/// <summary> /// Invoked on failure to receive a response. /// </summary> /// <param name="pack">Package detailing response data, if available.</param> /// <param name="x">Exception which caused failure.</param> protected virtual void OnInternalResponseReceiveFailed(Package pack, Exception x) { bool res; if (pack.Header.Type == PackageType.InternalResponse) res = PendingInternalRequests.DeclareFailure(pack.Header.IDTop, x, false); else res = PendingRequests.DeclareFailure(pack.Header.IDTop, x, false); if (res) { // All good. } #if DEBUG else { System.Diagnostics.Debug.WriteLine(string.Format("Failed to receive response {0} of type {1}!", pack.Header.IDTop, pack.Header.IDBottom)); } #endif }
/// <summary> /// Invoked on failure to send a response. /// </summary> /// <param name="pack">Package detailing response data.</param> /// <param name="x">Exception which caused failure.</param> protected virtual void OnInternalResponseSendFailed(Package pack, Exception x) { /*var id = pack.Header.IDTop; if (PendingRequests.ContainsKey(id)) { var sr = PendingRequests[id]; PendingRequests.Remove(id); sr.timeouttimer.Dispose(); //if (!sr.req.Disposed) // What on Earth was I thinking?! if (sr.req.Pending) sr.req.DeclareFailure(x, true); }*/ #if DEBUG //else { System.Diagnostics.Debug.WriteLine(string.Format("Failed to send response {0} of type {1}!", pack.Header.IDTop, pack.Header.IDBottom)); } #endif }
public QueuedPackage(byte[] pl, AsyncCallback cbk, Package st) { Data = pl; AsynchronousCallback = cbk; PackageObject = st; }