示例#1
0
 /// <summary>
 /// Sends a view model data to one or more clients.
 /// </summary>
 /// <param name="vmInfo">View model info.</param>
 /// <param name="args">Arguments containing information on clients to send to.</param>
 private void Send(VMInfo vmInfo, GroupSend args)
 {
     ResponseVMFilter.Invoke(vmInfo, args, filteredData =>
     {
         VMResponse(MULTICAST + nameof(GroupSend), vmInfo.Id, JsonSerializer.Serialize(args));
         return(Task.CompletedTask);
     });
 }
示例#2
0
        /// <summary>
        /// Push property changed updates on a view model back to the client.
        /// </summary>
        /// <param name="vmInfo">View model.</param>
        /// <param name="vmData">Serialized data to be pushed. If null, it's coming from the view model.</param>
        protected virtual void PushUpdates(VMInfo vmInfo, string vmData)
        {
            if (string.IsNullOrEmpty(vmData))
            {
                return;
            }

            ResponseVMFilter.Invoke(vmInfo, vmData, filteredData =>
            {
                var vmDataToSend = filteredData is GroupSend ? (filteredData as GroupSend).Data : (string)filteredData;
                VMResponse(vmInfo.ConnectionId, vmInfo.Id, vmDataToSend);
                return(Task.CompletedTask);
            });
        }
示例#3
0
        /// <summary>
        /// Push property changed updates on all view models back to the client.
        /// </summary>
        protected virtual void PushUpdates()
        {
            foreach (var kvp in _activeVMs)
            {
                var vmInstance = kvp.Value.Instance;
                lock (vmInstance)
                {
                    var changedProperties = new Dictionary <string, object>(vmInstance.ChangedProperties);
                    if (changedProperties.Count > 0)
                    {
                        var vmData = Serialize(changedProperties);

                        ResponseVMFilter.Invoke(kvp.Key, vmInstance, vmData, filteredData =>
                        {
                            _vmResponse(kvp.Value.ConnectionId, kvp.Key, (string)filteredData);

                            // After the changes are forwarded, accept the changes so they won't be marked as changed anymore.
                            vmInstance.AcceptChangedProperties();
                        });
                    }
                }
            }
        }
示例#4
0
        /// <summary>
        /// Handles a request for a view model from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="vmArg">Optional view model's initialization argument.</param>
        /// <returns>Group name, if the request is for a multicast view model associated with one.</returns>
        public async virtual Task <string> OnRequestVMAsync(string connectionId, string vmId, object vmArg = null)
        {
            BaseVM vmInstance = null;

            if (_activeVMs.ContainsKey(vmId))
            {
                vmInstance = _activeVMs[vmId].Instance;
            }
            else
            {
                // Create a new view model instance whose class name is matching the given VMId.
                vmInstance = CreateVM(vmId, vmArg);

                // Let the instance complete its initialization. If multicast, make sure it's only called once.
                if ((vmInstance as MulticastVM)?.RaiseCreatedEvent != false)
                {
                    await vmInstance.OnCreatedAsync();
                }
            }

            await RequestVMFilter.Invoke(vmId, vmInstance, vmArg, async data =>
            {
                string vmData    = vmInstance.Serialize();
                string groupName = vmInstance is MulticastVM ? (vmInstance as MulticastVM).GroupName : null;

                // Send the view model data back to the browser client.
                await ResponseVMFilter.Invoke(new VMInfo(vmId, vmInstance, connectionId, groupName), vmData, filteredData => VMResponse(connectionId, vmId, (string)filteredData));

                // Reset the changed property states unless it's a multicast.
                if (vmInstance is MulticastVM == false)
                {
                    vmInstance.AcceptChangedProperties();
                }

                // Add the view model instance to the controller.
                if (!_activeVMs.ContainsKey(vmId))
                {
                    var vmInfo = new VMInfo(id: vmId, instance: vmInstance, connectionId: connectionId, groupName: groupName);
                    vmInstance.RequestPushUpdates += VmInstance_RequestPushUpdates;
                    if (vmInstance is MulticastVM)
                    {
                        var multicastVM = vmInstance as MulticastVM;
                        multicastVM.RequestMulticastPushUpdates += VMInstance_RequestMulticastPushUpdates;
                        multicastVM.RequestSend += VMInstance_RequestSend;
                    }
                    _activeVMs.TryAdd(vmId, vmInfo);
                }
                else
                {
                    _activeVMs[vmId].ConnectionId = connectionId;
                }

                // If this request causes other view models to change, push those new values back to the client.
                foreach (var vmInfo in _activeVMs.Values)
                {
                    PushUpdates(vmInfo);
                }
            });

            return(_activeVMs[vmId].GroupName);
        }