private void GenerateEvents() { // For every event we have to compile a method that essentially does the same that the proxy compiler // does for interface methods: serialize the arguments into a stream and then call IEndPointChannel.Invoke EventInfo[] allEvents = InterfaceType.GetEvents(); foreach (EventInfo @event in allEvents) { GenerateEvent(@event); } }
public void AddClientSubscription <T, I>(Connection connection) where T : I { if (SubscribedClients.ContainsKey(connection.ConnectionInfo.NetworkIdentifier)) { return; } var events = InterfaceType.GetEvents(); var addedHandlers = new Dictionary <EventInfo, Delegate>(); foreach (var ev in events) { var addMethod = ev.GetAddMethod(); var evGenerator = typeof(RemoteProcedureCalls.Server.RPCRemoteObject).GetMethod("GenerateEvent", BindingFlags.NonPublic | BindingFlags.Static); evGenerator = evGenerator.MakeGenericMethod(ev.EventHandlerType.GetGenericArguments()); var handler = evGenerator.Invoke(null, new object[] { connection, InstanceId, InterfaceType, ev.Name }); addMethod.Invoke(obj, new object[] { handler }); addedHandlers.Add(ev, handler as Delegate); } var callFunctionDelegate = new NetworkComms.PacketHandlerCallBackDelegate <RemoteCallWrapper>(RunRPCFunctionHandler <T, I>); var removeDelegate = new NetworkComms.PacketHandlerCallBackDelegate <RemoteCallWrapper>(RPCDisconnectHandler <T, I>); var subscripion = new RPCClientSubscription(connection, callFunctionDelegate, removeDelegate); foreach (var handlerPair in addedHandlers) { subscripion.SubscribedEvents.Add(handlerPair.Key, handlerPair.Value); } SubscribedClients.Add(connection.ConnectionInfo.NetworkIdentifier, subscripion); connection.AppendIncomingPacketHandler <RemoteCallWrapper>(InterfaceType.Name + "-RPC-CALL-" + InstanceId, callFunctionDelegate); connection.AppendIncomingPacketHandler <RemoteCallWrapper>(InterfaceType.Name + "-REMOVE-REFERENCE-" + InstanceId, removeDelegate); LastAccess = DateTime.Now; //If the connection is closed make sure we remove all event handlers associated with that connection so that we don't get exceptions on the event fire //Note we don't want to remove the client object itself connection.AppendShutdownHandler((clientConnection) => { RemoveClientSubscription(clientConnection); }); }
private void CreateDelegateHolders() { var bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy; DelegateHolders = new Dictionary <string, IDelegateHolder>(); EventProperties = InterfaceType.GetEvents(bindingFlags); DelegateProperties = InterfaceType.GetProperties(bindingFlags) .Where(p => typeof(Delegate).IsAssignableFrom(p.PropertyType)) .ToArray(); foreach (var eventProperty in EventProperties) { DelegateHolders[eventProperty.Name] = CreateDelegateHolder(eventProperty.EventHandlerType); } foreach (var delegateProperty in DelegateProperties) { DelegateHolders[delegateProperty.Name] = CreateDelegateHolder(delegateProperty.PropertyType); } }