Exemplo n.º 1
0
 /// <summary>
 /// Handler method to create a network channel
 /// </summary>
 /// <returns>The network channel.</returns>
 /// <param name="scope">The scope calling the method.</param>
 /// <param name="attr">The channel attribute.</param>
 /// <param name="type">The type to create the channel for</param>
 private static IUntypedChannel Creator(ChannelScope scope, ChannelNameAttribute attr, Type type)
 {
     return
         ((IUntypedChannel)typeof(NetworkChannelScope)
          .GetMethod(nameof(CreateNetworkChannel), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.NonPublic)
          .MakeGenericMethod(type)
          .Invoke(scope, new object[] { attr }));
 }
Exemplo n.º 2
0
        /// <summary>
        /// Runs the channel handler.
        /// </summary>
        /// <param name="nwc">The network client used for communicating.</param>
        /// <param name="sc">The scope where channels are created.</param>
        protected static async void RunChannelHandler(NetworkClient nwc, ChannelScope sc)
        {
            await nwc.ConnectAsync();

            var transactions = new Dictionary <string, TwoPhaseNetworkHandler>();
            var lck          = new object();

            using (nwc)
                while (true)
                {
                    var req = await nwc.ReadAsync();

                    // If this is a channel creation request, hijack it here
                    if (req.RequestType == NetworkMessageType.CreateChannelRequest)
                    {
                        var chancfg = req.Value as ChannelNameAttribute;
                        sc.GetOrCreate(chancfg, req.ChannelDataType);
                        continue;
                    }

                    var chan = sc.GetOrCreate(req.ChannelID, req.ChannelDataType);

                    switch (req.RequestType)
                    {
                    case NetworkMessageType.JoinRequest:
                        ((IJoinAbleChannel)chan).Join((bool)req.Value);
                        break;

                    case NetworkMessageType.LeaveRequest:
                        ((IJoinAbleChannel)chan).Leave((bool)req.Value);
                        break;

                    case NetworkMessageType.RetireRequest:
                        chan.Retire((bool)req.Value);
                        break;

                    case NetworkMessageType.OfferAcceptResponse:
                        transactions[req.RequestID].Accepted();
                        break;

                    case NetworkMessageType.OfferDeclineResponse:
                        transactions[req.RequestID].Denied();
                        break;

                    case NetworkMessageType.ReadRequest:
                        lock (lck)
                            transactions[req.RequestID] = req.NoOffer ? null : new TwoPhaseNetworkHandler(req, nwc);

                        ((IUntypedChannel)chan).ReadAsync(TimeoutToTimeSpan(req.Timeout), transactions[req.RequestID]).ContinueWith(async x =>
                        {
                            NetworkMessageType responsetype;
                            object responseitem = null;

                            if (x.IsCanceled)
                            {
                                responsetype = NetworkMessageType.CancelResponse;
                            }
                            else if (x.IsFaulted && x.Exception.IsRetiredException())
                            {
                                responsetype = NetworkMessageType.RetiredResponse;
                            }
                            else if (x.IsFaulted && x.Exception.IsTimeoutException())
                            {
                                responsetype = NetworkMessageType.TimeoutResponse;
                            }
                            else if (x.IsFaulted)
                            {
                                responsetype = NetworkMessageType.FailResponse;
                                responseitem = x.Exception;
                            }
                            else
                            {
                                responsetype = NetworkMessageType.ReadResponse;
                                responseitem = await x;
                            }

                            lock (lck)
                                transactions.Remove(req.RequestID);

                            await nwc.WriteAsync(new PendingNetworkRequest(
                                                     req.ChannelID,
                                                     req.ChannelDataType,
                                                     req.RequestID,
                                                     req.SourceID,
                                                     new DateTime(0),
                                                     responsetype,
                                                     responseitem,
                                                     true
                                                     ));
                        }).FireAndForget();

                        break;

                    case NetworkMessageType.WriteRequest:
                        lock (lck)
                            transactions[req.RequestID] = req.NoOffer ? null : new TwoPhaseNetworkHandler(req, nwc);

                        ((IUntypedChannel)chan).WriteAsync(req.Value, TimeoutToTimeSpan(req.Timeout), transactions[req.RequestID]).ContinueWith(async x =>
                        {
                            NetworkMessageType responsetype;
                            object responseitem = null;

                            if (x.IsCanceled)
                            {
                                responsetype = NetworkMessageType.CancelResponse;
                            }
                            else if (x.IsFaulted && x.Exception.IsRetiredException())
                            {
                                responsetype = NetworkMessageType.RetiredResponse;
                            }
                            else if (x.IsFaulted && x.Exception.IsTimeoutException())
                            {
                                responsetype = NetworkMessageType.TimeoutResponse;
                            }
                            else if (x.IsFaulted)
                            {
                                responsetype = NetworkMessageType.FailResponse;
                                responseitem = x.Exception;
                            }
                            else
                            {
                                responsetype = NetworkMessageType.WriteResponse;
                            }

                            lock (lck)
                                transactions.Remove(req.RequestID);

                            await nwc.WriteAsync(new PendingNetworkRequest(
                                                     req.ChannelID,
                                                     req.ChannelDataType,
                                                     req.RequestID,
                                                     req.SourceID,
                                                     new DateTime(0),
                                                     responsetype,
                                                     responseitem,
                                                     true
                                                     ));
                        }).FireAndForget();

                        break;

                    default:
                        throw new Exception("Unsupported message: {0}");
                    }
                }
        }