public override void OnSend(Event e) { if (!hasSent && e.GetTypeId() != BuiltinEventType.HeartbeatEvent) { hasSent = true; } }
protected override void OnEventReceived(Event e) { TraceLevel traceLevel = (e.GetTypeId() == BuiltinEventType.HeartbeatEvent ? TraceLevel.Trace : TraceLevel.Debug); Trace.Emit(traceLevel, "{0} {1} received event {2}", link.Name, InternalHandle, e); base.OnEventReceived(e); }
public override bool Process(Event e) { switch (e.GetTypeId()) { case BuiltinEventType.HeartbeatEvent: // Do nothing break; default: return(false); } return(true); }
private void UnbindInternal(Event e, Handler handler) { HandlerSet handlers; if (!handlerMap.TryGetValue(e, out handlers)) { return; } if (!handlers.Remove(handler)) { return; } if (handlers.Count == 0) { handlerMap.Remove(e); } filter.Remove(e.GetTypeId(), e.GetFingerprint()); }
/// <summary> /// Registers the specified type as a retrievable event. /// </summary> public void Register(Type type) { int typeId; Func <Event> factoryMethod; #if UNITY_WORKAROUND // To avoid reflection calls on System.Type class Event e = (Event)Activator.CreateInstance(type); typeId = e.GetTypeId(); factoryMethod = e.GetFactoryMethod(); #else PropertyInfo prop = type.GetProperty("TypeId", BindingFlags.Public | BindingFlags.Static); typeId = (int)prop.GetValue(null, null); MethodInfo method = type.GetMethod("New", BindingFlags.Public | BindingFlags.Static); factoryMethod = (Func <Event>) Delegate.CreateDelegate(typeof(Func <Event>), method); #endif Register(typeId, factoryMethod); }
public override bool Process(Event e) { switch (e.GetTypeId()) { case (int)LinkEventType.HandshakeReq: { var req = (HandshakeReq)e; var resp = new HandshakeResp { _Transform = false }; byte[] response = null; try { ManualResetEvent waitHandle = SignalPool.Acquire(Session.InternalHandle); waitHandle.WaitOne(new TimeSpan(0, 0, 30)); SignalPool.Release(Session.InternalHandle); response = BufferTransform.Handshake(req.Data); } catch (Exception ex) { Trace.Error("{0} {1} error handshaking : {2}", Session.Link.Name, Session.InternalHandle, ex.ToString()); } if (response != null) { resp.Data = response; } Session.Send(resp); } break; case (int)LinkEventType.HandshakeResp: { var ack = new HandshakeAck { _Transform = false }; var resp = (HandshakeResp)e; try { if (BufferTransform.FinalizeHandshake(resp.Data)) { rxTransformReady = true; ack.Result = true; } } catch (Exception ex) { Trace.Error("{0} {1} error finishing handshake : {2}", Session.Link.Name, Session.InternalHandle, ex.ToString()); } Session.Send(ack); } break; case (int)LinkEventType.HandshakeAck: { var ack = (HandshakeAck)e; bool result = ack.Result; if (result) { txTransformReady = true; } Session.Link.OnLinkSessionConnectedInternal(result, (result ? Session: null)); } break; default: return false; } return true; }
protected void OnReceiveFromInternal(int bytesTransferred, EndPoint endPoint) { Diag.AddBytesReceived(bytesTransferred); int handle; using (new ReadLock(rwlock)) { if (!reverseMap.TryGetValue(endPoint, out handle)) { handle = 0; } } rxBuffer.Stretch(bytesTransferred); if (BufferTransform != null) { try { BufferTransform.InverseTransform(rxBuffer, (int)rxBuffer.Length); } catch (Exception e) { Trace.Error("{0} {1} buffer inv transform error: {2}", Name, handle, e.Message); return; } } rxBuffer.Rewind(); var deserializer = new Deserializer(rxBuffer, EventFactory); int typeId; try { deserializer.Read(out typeId); } catch (System.IO.EndOfStreamException) { // Need more return; } Event retrieved = CreateEvent(typeId); if (ReferenceEquals(retrieved, null)) { Trace.Error("{0} {1} unknown event type id {2}", Name, handle, typeId); return; } else { try { retrieved.Deserialize(deserializer); } catch (Exception e) { Trace.Error("{0} {1} error loading event {2}: {3}", Name, handle, retrieved.GetTypeId(), e.ToString()); return; } if (handle != 0) { retrieved._Handle = handle; } Hub.Post(retrieved); Diag.IncrementEventsReceived(); Trace.Debug("{0} {1} received event {2}", Name, handle, retrieved); } }
private void BeginSendTo(Event e) { int handle = e._Handle; EndPoint endPoint; using (new ReadLock(rwlock)) { int count = map.Count; if (count == 0) { Trace.Error("{0} no known peers - dropped event {1}", Name, e); goto next; } if (count == 1 && handle == 0) { endPoint = map.Values[0]; } else { if (!map.TryGetValue(handle, out endPoint)) { Trace.Error("{0} unknown handle {1} - dropped event {2}", Name, handle, e); goto next; } } } // Apply the datagram length limit. int length = e.GetLength(); if (length > txBuffer.BlockSize) { Trace.Error("{0} dropped big event {1}", Name, e); goto next; } txBuffer.Reset(); Serializer serializer = new Serializer(txBuffer); serializer.Write(e.GetTypeId()); e.Serialize(serializer); if (BufferTransform != null) { BufferTransform.Transform(txBuffer, (int)txBuffer.Length); } try { SendToInternal(endPoint); Diag.IncrementEventsSent(); if (Trace.Handler != null && Config.TraceLevel <= TraceLevel.Debug) { // e.ToString() may crash if a composite property (list for example) // of the event is changed in other threads. string description; try { description = e.ToString(); } catch { description = e.GetTypeTag().RuntimeType.Name; } Trace.Emit(TraceLevel.Debug, "{0} {1} sent event {2}", Name, handle, description); } return; } catch (ObjectDisposedException) { return; } catch (Exception ex) { Trace.Info("{0} send error {1}", Name, ex); } next: OnSendToInternal(0); }
protected void OnReceiveInternal(int bytesTransferred) { Diag.AddBytesReceived(bytesTransferred); if (HasHeartbeatStrategy) { HeartbeatStrategy.OnReceive(); } lock (syncRoot) { if (disposed) { return; } rxBuffer.Stretch(bytesTransferred); } if (Config.TraceLevel <= TraceLevel.Trace) { Trace.Log("{0} {1} recv {2}: {3}", link.Name, InternalHandle, bytesTransferred, rxBuffer.ToHexString()); } if (rxBeginning) { rxBuffer.Rewind(); if (!ParseHeader()) { BeginReceive(true); return; } } // Handle split packets. if (rxBuffer.Length < lengthToReceive) { BeginReceive(false); return; } while (true) { rxBuffer.MarkToRead(lengthToReceive); Trace.Log("{0} {1} marked {2} byte(s) to read", link.Name, InternalHandle, lengthToReceive); if (HasChannelStrategy && rxTransformed) { try { ChannelStrategy.AfterReceive(rxBuffer, lengthToReceive); } catch (Exception e) { Trace.Error("{0} {1} buffer inv transform error: {2}", link.Name, InternalHandle, e.Message); goto next; } } rxBuffer.Rewind(); var deserializer = new Deserializer(rxBuffer, link.EventFactory); int typeId; try { deserializer.Read(out typeId); } catch (System.IO.EndOfStreamException) { // Need more goto next; } Event retrieved = link.CreateEvent(typeId); if (ReferenceEquals(retrieved, null)) { Trace.Error("{0} {1} unknown event type id {2}", link.Name, InternalHandle, typeId); goto next; } else { try { retrieved.Deserialize(deserializer); } catch (Exception e) { Trace.Error("{0} {1} error loading event {2}: {3}", link.Name, InternalHandle, retrieved.GetTypeId(), e.ToString()); goto next; } OnEventReceived(retrieved); // Consider subscribing/unsubscribing here. bool processed = false; if (HasChannelStrategy) { processed = ChannelStrategy.Process(retrieved); } if (!processed && HasHeartbeatStrategy) { processed = HeartbeatStrategy.Process(retrieved); } if (!processed) { processed = Process(retrieved); } if (!processed) { retrieved._Handle = Handle; link.OnPreprocess(this, retrieved); Hub.Post(retrieved); } } next: rxBuffer.Trim(); if (rxBuffer.IsEmpty || !ParseHeader()) { break; } if (rxBuffer.Length < lengthToReceive) { BeginReceive(false); return; } } BeginReceive(true); }
internal void BeginSend() { lock (syncRoot) { if (eventsToSend.Count == 0) { return; } // Swap the event buffers. if (eventsSending.Count != 0) { eventsSending.Clear(); } List <Event> temp = eventsSending; eventsSending = eventsToSend; eventsToSend = temp; temp = null; } // Capture send buffers. txBufferList.Clear(); lengthToSend = 0; int count = eventsSending.Count; int bufferCount = txBuffers.Count; if (bufferCount < count) { for (int i = 0, n = count - bufferCount; i < n; ++i) { txBuffers.Add(new SendBuffer()); } } else { for (int i = 0, n = bufferCount - count; i < n; ++i) { int j = bufferCount - (i + 1); txBuffers[j].Dispose(); txBuffers.RemoveAt(j); } } for (int i = 0; i < count; ++i) { Event e = eventsSending[i]; var sendBuffer = txBuffers[i]; sendBuffer.Reset(); int typeId = e.GetTypeId(); Trace.Log("{0} {1} buffering event type {2} to send (#{3}/{4})", link.Name, InternalHandle, typeId, i + 1, count); Serializer serializer = new Serializer(sendBuffer.Buffer); serializer.Write(typeId); e.Serialize(serializer); bool transformed = false; if (HasChannelStrategy && e._Transform) { transformed = ChannelStrategy.BeforeSend(sendBuffer.Buffer, (int)sendBuffer.Buffer.Length); } BuildHeader(sendBuffer, transformed); sendBuffer.ListOccupiedSegments(txBufferList); lengthToSend += sendBuffer.Length; OnEventSent(e); } Trace.Log("{0} {1} serialized {2} events to send ({3} bytes)", link.Name, InternalHandle, count, lengthToSend); SendInternal(); }