/// <summary>
 /// Add a new subscription for a certain service
 /// </summary>
 /// <param name="tag">The TypeTag for which to add the listener</param>
 /// <param name="listener">Listener to add (must be an instance of ServiceListener)</param>
 /// <returns>Returns a ServiceSubscription, which can be used to manage your subscription</returns>
 public ServiceSubscription AddServiceSubscription(TypeTag tag, ServiceListenerBase listener)
 {
     // Try to get the list of listeners, then add it. If it doesn't exist, create one first
     List<ServiceListenerBase> listenerList;
     // Try to get the list if it exists (and add the listener to it)
     if (serviceSubscriptions.TryGetValue(tag, out listenerList))
         listenerList.Add(listener);
     else
     {
         // Otherwise create a new list and add it
         listenerList = new List<ServiceListenerBase> { listener };
         serviceSubscriptions.Add(tag, listenerList);
     }
     // Now create an Action which can later be invoked by the user to cancel his subscription
     Action remover = () =>
     {
         // Try to remove it from the list of listeners (categorized by TypeTag)
         // If it's the only element left in the list, just remove the entry as a whole
         List<ServiceListenerBase> listenerList_;
         if (serviceSubscriptions.TryGetValue(tag, out listenerList_))
             if (listenerList.Count > 1)
                 listenerList_.Remove(listener);
             else
                 serviceSubscriptions.Remove(tag);
     };
     // Now return an instance of ServiceSubscription so the user can manage his subscription
     return new ServiceSubscription(remover);
 }
        /// <summary>
        /// Add a new service to the list of imported services.
        /// Will trigger the ServiceDisconnectedEvent or ServiceReconnectedEvent (whichever is appropriate)
        /// Will also ignore any service if it has already been imported
        /// </summary>
        /// <param name="serviceIdentifier">The identifier of the service</param>
        /// <param name="sourceAddress">The address which exported the service</param>
        /// <param name="serviceImplementation">The actual exported service</param>
        public void AddService(TypeTag typeTag, Guid serviceIdentifier, string sourceAddress, object serviceImplementation)
        {
            // If the service has already been imported - ignore it
            if (this.importedServices.ContainsKey(serviceIdentifier))
                return;

            this.importedServices.Add(serviceIdentifier, serviceImplementation);
            this.importedServiceTypeTags.Add(serviceIdentifier, typeTag);

            // Check if we have already imported other services from this particular client. If yes, add this particular service to the list of his services.
            // Otherwise add an entirely new set (containing only one service for now - until we discover more of his services).
            if (this.importedServiceAddresses.ContainsKey(sourceAddress))
                this.importedServiceAddresses[sourceAddress].Add(serviceIdentifier);
            else
                this.importedServiceAddresses.Add(sourceAddress, new List<Guid>() { serviceIdentifier });

            // Check if the service has previously been disconnected from the network
            // If yes, trigger the reconnected event - otherwise trigger the discovered event
            if(this.diconnectedServices.Contains(serviceIdentifier))
            {
                if(this.ServiceReconnectedEvent != null)
                    this.ServiceReconnectedEvent(this, new ServiceNotificationEventArgs(serviceIdentifier, sourceAddress, typeTag, serviceImplementation));
                this.diconnectedServices.Remove(serviceIdentifier);
            }
            else
            {
                if(this.ServiceDiscoveredEvent != null)
                    this.ServiceDiscoveredEvent(this, new ServiceNotificationEventArgs(serviceIdentifier, sourceAddress, typeTag, serviceImplementation));
            }
        }
        /// <summary>
        /// Export a certain service. This service will link the given serviceImplementation to the provided TypeTag.
        /// When the ServiceImplementation implements the UObject interface, a RemoteReference will be returned.
        /// Otherwise the ServiceImplementation itself will be returned.
        /// When the same object is exported twice, it will be handled as a new service. The instance will be stored as if it was new.
        /// This will also generate a new RemoteReference.
        /// </summary>
        /// <param name="tag">TypeTag which identifies the service which needs to be exported</param>
        /// <param name="serviceImplementation">Service implementation to export (make available on the network)</param>
        /// <param name="identifier">Output parameter which will give you the identifier associated with the service implementation</param>
        /// <returns>Returns an object which can be used to transmit to other devices (either the ServiceImplementation itself or a RemoteReference)</returns>
        public object ExportService(TypeTag tag, object serviceImplementation, out Guid identifier)
        {
            // Check if the typetag already has exported service implementations
            identifier = Guid.NewGuid();
            if (!services.ContainsKey(tag))
                services.Add(tag, new List<Guid>() { identifier });
            else
            {
                // If an implementation already exists - add a new implementation to the existing list
                List<Guid> _services;
                if (services.TryGetValue(tag, out _services))
                    _services.Add(identifier);
            }

            // Now add the service implementation to the list of exported services
            this.exportedObjects.Add(identifier, serviceImplementation);

            // If the service is a UObject, we should refer to it with a remote reference. Store this too! (and return a RemoteReference)
            if (serviceImplementation is UObject)
            {
                RemoteReference remoteReference = new RemoteReference(tag, identifier);
                this.AddRemoteReference(identifier, remoteReference);
                // Returns the RemoteReference as "exportable object"
                return remoteReference;
            }
            // Otherwise just return the implementation itself
            return serviceImplementation;
        }
        public RemoteReference AddParameterReferencedObject(object obj)
        {
            TypeTag typeTag = new TypeTag("");
            Guid identifier = Guid.NewGuid();
            RemoteReference remoteReference = new RemoteReference(typeTag, identifier);
            // Change the typetag to something unique - to make sure it wouldn't be found as a service when looking up the object this remoteReference belongs to
            //remoteReference.serviceTag.tag = identifier.ToString();
            this.exportedObjects.Add(identifier, obj);
            this.remoteReferences.Add(identifier, remoteReference);

            return remoteReference;
        }
Esempio n. 5
0
        public MainPage()
        {
            this.InitializeComponent();

  
            UIDispatcher = (Windows.UI.Core.DispatchedHandler a) => this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, a);

            this.chatServiceTag = new TypeTag("chat");

            MyChatUsersViewModel = (ChatUsersViewModel)Resources["ChatUsersViewModel"];
            this.chatUsers = new Dictionary<Guid, RemoteReference>();

            // Set up our own name
            string nickname = "User" + new Random().Next(1, 99);
            ui_nickname.Text = nickname;
            ui_nickname.IsEnabled = false;

            // Set up our own user and all callbacks
            myChatUser = new ChatUser(nickname, this.UIDispatcher);
            myChatUser.PartnerLeftChatEvent += PartnerLeftChat;
            myChatUser.InviteReceivedEvent += InviteReceivedFromUser;
            myChatUser.AcceptInviteEvent += AcceptInviteByUser;
            myChatUser.RejectInviteEvent += RejectInviteByUser;
            myChatUser.InviteAcceptedEvent += InviteAcceptedByUser;
            myChatUser.InviteRejectedEvent += InviteRejectedByUser;

            // Set up the listener callbacks for joining/leaving of users
            this.userListener = new ServiceListener<RemoteReference>();
            userListener.IsDiscovered += UserListener_IsDiscovered;
            userListener.IsDisconnected += UserListener_IsDisconnected;
            userListener.IsReconnected += UserListener_IsDiscovered;
            EventLoop.Instance.Whenever(chatServiceTag, userListener);

            // Export our service
            myServicePublication = EventLoop.Instance.Broadcast(chatServiceTag, myChatUser);

            // Go online on the network
            NetPOC.Network.NetworkControl.Network networkObj = EventLoop.Instance.GoOnline();
        }
Esempio n. 6
0
 public RemoteReference(TypeTag service, Guid guid)
 {
     this.serviceTag = service;
     this.guid = guid;
 }
 /// <summary>
 /// Get all ServiceListeners for a given service (identified by TypeTag)
 /// If no listeners are registered (or the typetag is unknown), the empty list will be returned.
 /// </summary>
 /// <param name="tag">Service to get the listeners for. Will return an empty list if typetag isn't know or has no listeners</param>
 public List<ServiceListenerBase> GetServiceListeners(TypeTag tag)
 {
     List<ServiceListenerBase> listeners;
     if (this.serviceSubscriptions.TryGetValue(tag, out listeners))
         return listeners;
     else
         return new List<ServiceListenerBase>();
 }
Esempio n. 8
0
 /// <summary>
 /// Disconnect a certain service from the network
 /// </summary>
 /// <param name="serviceIdentifier">The identifier of the service you're disconnecting</param>
 /// <param name="typetag">TypeTag by which the service is identified on the network</param>
 /// <param name="service">Service which has previously been broadcast on the network</param>
 /// <returns></returns>
 public void DisconnectService(Guid serviceIdentifier, TypeTag typetag, object service)
 {
     PeerConnector.Instance.BroadcastNetworkObject(new NetworkDisconnectService(serviceIdentifier, typetag, service));
 }
 /// <summary>
 /// Given a TypeTag (to identify the service), get a list of all exported services linked to this typetag.
 /// The "exported service" may be a RemoteReference (if the service implementation is a UObject), but it can also be the actual service implementation itself.
 /// The returned services are what's exported to other devices.
 /// </summary>
 /// <param name="service">TypeTag which identifies the required service</param>
 /// <param name="serviceIdentifiers">Output parameters which gives you the list of identifiers associated with the returned list of service implementations</param>
 /// <returns>Returns a list of objects which can be sent to other devices. The objects in this list are what's exported when exporting a service (RemoteReference, string, int, etc)</returns>
 public List<object> GetExportedServices(TypeTag service, out List<Guid> serviceIdentifiers)
 {
     List<object> _services = new List<object>();
     List<Guid> exportedServices;
     if (this.services.TryGetValue(service, out exportedServices))
     {
         foreach (Guid serviceGuid in exportedServices)
         {
             // First - try to get a RemoteReference. If this doesn't exist - export the service implementation
             RemoteReference remoteRef;
             object _service;
             if (remoteReferences.TryGetValue(serviceGuid, out remoteRef))
                 _services.Add(remoteRef);
             else if (exportedObjects.TryGetValue(serviceGuid, out _service))
                 _services.Add(_service);
         }
     }
     serviceIdentifiers = exportedServices;
     return _services;
 }
Esempio n. 10
0
 /// <summary>
 /// Install a ServiceListener to listen for all services on the network of a particular TypeTag. 
 /// </summary>
 /// <param name="serviceTag">TypeTag which identifies the service</param>
 /// <param name="listener">The ServiceListener to install for this particular TypeTag</param>
 /// <returns>Returns a ServiceSubscription, which can be used to manage this subscription to a service (and for example cancel it)</returns>
 public ServiceSubscription Whenever(TypeTag serviceTag, ServiceListenerBase listener)
 {
     System.Diagnostics.Debug.WriteLine("Installing service listener for TypeTag " + serviceTag.tag);
     return discoveryManager.serviceManager.subscriptionManager.AddServiceSubscription(serviceTag, listener);
 }
Esempio n. 11
0
        /// <summary>
        /// Broadcast a service to the entire network
        /// </summary>
        /// <param name="serviceTag">label (TypeTag) which the service is announced as</param>
        /// <param name="serviceImplementation">Implementation of the service</param>
        /// <returns>Returns a ServicePublication, which can be used to control your publication of this particular service (and perhaps cancel it)</returns>
        public ServicePublication Broadcast(TypeTag serviceTag, object serviceImplementation)
        {
            ServiceManager serviceManager = discoveryManager.serviceManager;

            Guid identifier;
            // Export the service, which gets us an object which can be tranfered over the network.
            object transferableService = serviceManager.exportedServiceManager.ExportService(serviceTag, serviceImplementation, out identifier);

            // If we're connected to a network - broadcast the service
            if (this.connectedToNetwork)
            {
                // Now construct a new data packet to send over the network
                NetworkJoinService dataPacket = new NetworkJoinService(identifier, serviceTag, transferableService);
                // Broadcast the service over the network
                PeerConnector.Instance.BroadcastNetworkObject(dataPacket);
            }

            // Return a ServicePublication (also pass an anonymous function which removes the service again, so the user is capable of cancelling it)
            return new ServicePublication(identifier,
                () =>
                {
                    serviceManager.exportedServiceManager.RemoveExportedService(identifier);
                    this.discoveryManager.DisconnectService(identifier, serviceTag, transferableService);
                });
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="serviceIdentifier">Identifier of the referenced service</param>
 /// <param name="sourceAddress">The address of the device who exported the service</param>
 /// <param name="typetag">Typetag (or "category") the service is exported as</param>
 /// <param name="service">The service implementation of the service</param>
 public ServiceNotificationEventArgs(Guid serviceIdentifier, string sourceAddress, TypeTag typetag, object service)
 {
     this.serviceIdentifier = serviceIdentifier;
     this.sourceAddress = sourceAddress;
     this.typetag = typetag;
     this.service = service;
 }