Exemple #1
0
 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);
        }
Exemple #3
0
        public override bool Process(Event e)
        {
            switch (e.GetTypeId())
            {
            case BuiltinEventType.HeartbeatEvent:
                // Do nothing
                break;

            default:
                return(false);
            }
            return(true);
        }
Exemple #4
0
        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;
        }
Exemple #7
0
        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);
            }
        }
Exemple #8
0
        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();
        }