Пример #1
0
        private static void NewInstanceRPCHandler <T, I>(PacketHeader header, Connection connection, string instanceName) where T : I, new()
        {
            lock (locker)
            {
                string instanceId = GetInstanceId(typeof(T).Name + instanceName + connection.ConnectionInfo.NetworkIdentifier.ToString());

                RPCRemoteObject wrapper = null;
                if (!RPCObjectsById.TryGetValue(instanceId, out wrapper))
                {
                    var instance = new T();
                    wrapper = new RPCRemoteObject(instance, typeof(I), RPCRemoteObject.RPCObjectType.Private, instanceId, timeoutByInterfaceType[typeof(I)]);
                    RPCObjectsById.Add(instanceId, wrapper);
                }

                wrapper.AddClientSubscription <T, I>(connection);

                if (!newConnectionByIdHandlers.ContainsKey(typeof(I)))
                {
                    var del = new NetworkComms.PacketHandlerCallBackDelegate <string>(RetrieveByIDRPCHandler <T, I>);

                    serverConnection.AppendIncomingPacketHandler <string>(typeof(I).Name + "-NEW-RPC-CONNECTION-BY-ID", del);
                    newConnectionByIdHandlers.Add(typeof(I), del);
                }

                string returnPacketType = header.GetOption(PacketHeaderStringItems.RequestedReturnPacketType);
                connection.SendObject(returnPacketType, instanceId);
            }
        }
Пример #2
0
        private static void RunRPCFunctionHandler <T, I>(PacketHeader header, Connection connection, RemoteCallWrapper wrapper) where T : I
        {
            I          instance = default(I);
            MethodInfo funcRef  = typeof(I).GetMethod(wrapper.name);

            try
            {
                lock (locker)
                {
                    instance = (I)(RPCObjectsById[wrapper.instanceId].RPCObject);
                }
            }
            catch (Exception)
            {
                wrapper.result    = null;
                wrapper.Exception = "SERVER SIDE EXCEPTION\n\n" + "Invalid instanceID" + "\n\nEND SERVER SIDE EXCEPTION\n\n";
                connection.SendObject(header.PacketType, wrapper);
                return;
            }

            object[] args = null;

            if (wrapper.args == null)
            {
                args = new object[0];
            }
            else
            {
                args = (from arg in wrapper.args select arg.UntypedValue).ToArray();
            }

            try
            {
                wrapper.result = RPCArgumentBase.CreateDynamic(funcRef.Invoke(instance, args));
                wrapper.args   = (from arg in args select RPCArgumentBase.CreateDynamic(arg)).ToList();
            }
            catch (Exception e)
            {
                wrapper.result = null;

                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }

                wrapper.Exception = "SERVER SIDE EXCEPTION\n\n" + e.ToString() + "\n\nEND SERVER SIDE EXCEPTION\n\n";
            }

            string returnPacketType = header.GetOption(PacketHeaderStringItems.RequestedReturnPacketType);

            connection.SendObject(returnPacketType, wrapper);
        }
Пример #3
0
        private static void RetrieveByIDRPCHandler <T, I>(PacketHeader header, Connection connection, string instanceId) where T : I
        {
            lock (locker)
            {
                if (!RPCObjectsById.ContainsKey(instanceId) || RPCObjectsById[instanceId].InterfaceType != typeof(I))
                {
                    instanceId = String.Empty;
                }
                else
                {
                    var instanceWrapper = RPCObjectsById[instanceId];
                    instanceWrapper.AddClientSubscription <T, I>(connection);
                }

                string returnPacketType = header.GetOption(PacketHeaderStringItems.RequestedReturnPacketType);
                connection.SendObject(returnPacketType, instanceId);
            }
        }
Пример #4
0
        /// <summary>
        /// Handles an incoming packet of type 'PartialFileData'
        /// </summary>
        /// <param name="header">Header associated with incoming packet</param>
        /// <param name="connection">The connection associated with incoming packet</param>
        /// <param name="data">The incoming data</param>
        private void IncomingPartialFileData(PacketHeader header, Connection connection, byte[] data)
        {
            try
            {
                SendInfo     info = null;
                ReceivedFile file = null;

                //Perform this in a thread safe way
                lock (syncRoot)
                {
                    //Extract the packet sequence number from the header
                    //The header can also user defined parameters
                    long sequenceNumber = header.GetOption(PacketHeaderLongItems.PacketSequenceNumber);

                    if (incomingDataInfoCache.ContainsKey(connection.ConnectionInfo) && incomingDataInfoCache[connection.ConnectionInfo].ContainsKey(sequenceNumber))
                    {
                        //We have the associated SendInfo so we can add this data directly to the file
                        info = incomingDataInfoCache[connection.ConnectionInfo][sequenceNumber];
                        incomingDataInfoCache[connection.ConnectionInfo].Remove(sequenceNumber);

                        //Check to see if we have already received any files from this location
                        if (!receivedFilesDict.ContainsKey(connection.ConnectionInfo))
                        {
                            receivedFilesDict.Add(connection.ConnectionInfo, new Dictionary <string, ReceivedFile>());
                        }

                        //Check to see if we have already initialised this file
                        if (!receivedFilesDict[connection.ConnectionInfo].ContainsKey(info.Filename))
                        {
                            receivedFilesDict[connection.ConnectionInfo].Add(info.Filename, new ReceivedFile(info.Filename, connection.ConnectionInfo, info.TotalBytes));
                            AddNewReceivedItem(receivedFilesDict[connection.ConnectionInfo][info.Filename]);
                        }

                        file = receivedFilesDict[connection.ConnectionInfo][info.Filename];
                    }
                    else
                    {
                        //We do not yet have the associated SendInfo so we just add the data to the cache
                        if (!incomingDataCache.ContainsKey(connection.ConnectionInfo))
                        {
                            incomingDataCache.Add(connection.ConnectionInfo, new Dictionary <long, byte[]>());
                        }

                        incomingDataCache[connection.ConnectionInfo].Add(sequenceNumber, data);
                    }
                }

                //If we have everything we need we can add data to the ReceivedFile
                if (info != null && file != null && !file.IsCompleted)
                {
                    file.AddData(info.BytesStart, 0, data.Length, data);

                    //Perform a little clean-up
                    file = null;
                    data = null;
                    GC.Collect();
                }
                else if (info == null ^ file == null)
                {
                    throw new Exception("Either both are null or both are set. Info is " + (info == null ? "null." : "set.") + " File is " + (file == null ? "null." : "set.") + " File is " + (file.IsCompleted ? "completed." : "not completed."));
                }
            }
            catch (Exception ex)
            {
                //If an exception occurs we write to the log window and also create an error file
                AddLineToLog("Exception - " + ex.ToString());
                LogTools.LogException(ex, "IncomingPartialFileDataError");
            }
        }
        /// <summary>
        /// Returns the <see cref="SendReceiveOptions"/> to be used for the provided <see cref="PacketHeader"/>. Ensures there
        /// will not be a serializer or data processor clash for different delegate levels.
        /// </summary>
        /// <param name="header">The <see cref="PacketHeader"/> options are desired.</param>
        /// <returns>The requested <see cref="SendReceiveOptions"/></returns>
        internal SendReceiveOptions IncomingPacketSendReceiveOptions(PacketHeader header)
        {
            //Are there connection specific or global packet handlers?
            bool connectionSpecificHandlers = false;

            lock (_syncRoot) connectionSpecificHandlers = incomingPacketHandlers.ContainsKey(header.PacketType);

            bool globalHandlers = NetworkComms.GlobalIncomingPacketHandlerExists(header.PacketType);

            //Get connection specific options for this packet type, if there aren't any use the connection default options
            SendReceiveOptions connectionSpecificOptions = PacketTypeUnwrapperOptions(header.PacketType);

            if (connectionSpecificOptions == null)
            {
                connectionSpecificOptions = ConnectionDefaultSendReceiveOptions;
            }

            //Get global options for this packet type, if there aren't any use the global default options
            SendReceiveOptions globalOptions = NetworkComms.GlobalPacketTypeUnwrapperOptions(header.PacketType);

            if (globalOptions == null)
            {
                globalOptions = NetworkComms.DefaultSendReceiveOptions;
            }

            if (connectionSpecificHandlers && globalHandlers)
            {
                if (!connectionSpecificOptions.OptionsCompatible(globalOptions))
                {
                    throw new PacketHandlerException("Attempted to determine correct sendReceiveOptions for packet of type '" + header.PacketType + "'. Unable to continue as connection specific and global sendReceiveOptions are not equal.");
                }

                //We need to combine options in this case using the connection specific option in preference if both are present
                var combinedOptions = new Dictionary <string, string>(globalOptions.Options);

                foreach (var pair in connectionSpecificOptions.Options)
                {
                    combinedOptions[pair.Key] = pair.Value;
                }

                //If the header specifies a serializer and data processors we will auto detect those
                if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors))
                {
                    DataSerializer       serializer;
                    List <DataProcessor> dataProcessors;

                    DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors);
                    return(new SendReceiveOptions(serializer, dataProcessors, combinedOptions));
                }

                //Otherwise we will use options that were specified
                return(new SendReceiveOptions(connectionSpecificOptions.DataSerializer, connectionSpecificOptions.DataProcessors, combinedOptions));
            }
            //////////////////////////////////////////////
            //// Changed 20/05/14 to fix bug when encryption options is set on the listener and not the packet handler
            //////////////////////////////////////////////
            else //if (connectionSpecificHandlers)
            {
                //If the header specifies a serializer and data processors we will auto detect those
                if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors))
                {
                    DataSerializer       serializer;
                    List <DataProcessor> dataProcessors;

                    DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors);
                    return(new SendReceiveOptions(serializer, dataProcessors, connectionSpecificOptions.Options));
                }

                return(connectionSpecificOptions);
            }
            //else
            //{
            //    //If the header specifies a serializer and data processors we will auto detect those
            //    if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors))
            //    {
            //        DataSerializer serializer;
            //        List<DataProcessor> dataProcessors;

            //        DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors);
            //        return new SendReceiveOptions(serializer, dataProcessors, globalOptions.Options);
            //    }

            //    //If just globalHandlers is set (or indeed no handlers at all we just return the global options
            //    return globalOptions;
            //}
        }