示例#1
0
        public static void HandleReceivedPackages(ClientStateEventArgs e, Action <ClientStateEventArgs, IProtocolInfo> handleInnerProtocol)
        {
            string msg = string.Empty;

            if (e.LastPackages != null && e.LastPackages.Count > 0)
            {
                // 遍历接收到的多个封包数据
                foreach (var package in e.LastPackages)
                {
                    // 打开一个封包的内容,如果返回的结果为null,表示协议未知或者未能正常解析
                    IProtocolInfo protocol = ServerManager.DefaultPackageDealer.Open(package);
                    if (protocol != null)
                    {
                        if (handleInnerProtocol != null)
                        {
                            handleInnerProtocol.BeginInvoke(e, protocol, null, null);
                        }
                    }
                    else
                    {
                        logger.Debug("协议未知或者未能正常解析。");
                    }
                }
            }
            else
            {
                msg = e.LastReceivedMessage;

                logger.Debug("非协议消息" + msg);
            }
        }
示例#2
0
        public static void Send(IProtocolInfo info)
        {
            var messageThread = new Thread(() =>
            {
                try
                {
                    // 遍历所有客户端
                    foreach (var clientPair in StudentDevices)
                    {
                        var studentClient = clientPair.Value;

                        //if (modifyInfoByClient != null)
                        //{
                        //    modifyInfoByClient(clientPair);
                        //}

                        if (studentClient != null)
                        {
                            IPackageInfo package = DefaultPackageDealer.Seal(info);
                            TcpServer.SendAsync(studentClient, package.ToBytes());
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex);
                }
            });

            messageThread.Start();
        }
示例#3
0
 public ConfigurationWriter(string hostFileName, IConfigurationBuilder builder, IProtocolInfo protocolInfo,
                            IConfigurationReader reader)
 {
     if (string.IsNullOrEmpty(hostFileName))
     {
         throw new NullReferenceException(hostFileName);
     }
     _hostFile     = hostFileName;
     _protocolInfo = protocolInfo ?? throw new NullReferenceException(nameof(protocolInfo));
     _builder      = builder ?? throw new NullReferenceException(nameof(builder));
     _reader       = reader ?? throw new NullReferenceException(nameof(reader));
 }
示例#4
0
        /// <summary>
        /// 打开包裹得到协议
        /// </summary>
        /// <param name="package"></param>
        /// <returns></returns>
        public IProtocolInfo Open(IPackageInfo package)
        {
            IProtocolInfo result = null;

            string WrappedText = package.ToString();

            //test
            Console.WriteLine("WrappedText: {0}", WrappedText);

            result = DefaultResolver.ToEntity(WrappedText);

            return(result);
        }
示例#5
0
        /// <summary>
        /// 将协议封装成包裹
        /// </summary>
        /// <param name="protocol"></param>
        /// <returns></returns>
        public IPackageInfo Seal(IProtocolInfo protocol)
        {
            PackageInfo info = new PackageInfo();

            info.Prefix       = Encoding.UTF8.GetBytes(PackageSetting.PrefixString);
            info.BodyEncoding = PackageSetting.Encoding;

            string protocolPlainText = DefaultResolver.ToText(protocol);

            info.SetBodyFromString(protocolPlainText);

            info.BodyLength = BitConverter.GetBytes(Convert.ToInt32(info.Body.Length));

            return(info);
        }
示例#6
0
        public IProtocolInfo ToEntity(string protocolText)
        {
            IProtocolInfo info = null;

            JObject protocol = JObject.Parse(protocolText.ToLower());

            if (protocol != null)
            {
                switch (Convert.ToInt32(protocol["cmd"].ToString()))
                {
                case 100:
                    info = Deserialize <S2T_HeartbeatInfo>(protocolText);
                    break;

                case 101:
                    //info = Deserialize<S2T_ChatInfo>(protocolText);
                    break;

                case 102:
                    //info = Deserialize<S2T_ConnectInfo>(protocolText);
                    break;

                case 201:
                    info = Deserialize <S2T_ConnectInfo>(protocolText);
                    break;

                case 202:
                    info = Deserialize <S2T_Catchphrase>(protocolText);
                    break;

                case 203:
                    break;

                case 205:
                {
                    info = Deserialize <S2T_QuizCommit>(protocolText);
                }
                break;
                }
            }
            else
            {
                Console.WriteLine("未知类型");
            }

            return(info);
        }
示例#7
0
        public static void Draw(IProtocolInfo info, Vector2 offset, SpriteFont font, SpriteBatch spriteBatch)
        {
            if (!PixelTextures.ContainsKey(spriteBatch))
            {
                var pixelTexture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
                pixelTexture.SetData(new[] { Color.White });
                PixelTextures[spriteBatch] = pixelTexture;
            }

            // Settings.
            const int graphWidth = 180, graphHeight = 40;

            // Precompute stuff.
            int minIncoming = int.MaxValue,
                maxIncoming = 0,
                avgIncoming = 0,
                minOutgoing = int.MaxValue,
                maxOutgoing = 0,
                avgOutgoing = 0,
                minTotal    = int.MaxValue,
                maxTotal    = 0,
                avgTotal    = 0;

            var values = new Tuple <int, Color> [Math.Max(info.IncomingTraffic.Count, info.OutgoingTraffic.Count) - 1][];

            for (var i = 0; i < values.Length; ++i)
            {
                values[i] = new[]
                {
                    Tuple.Create(0, Color.White),
                    Tuple.Create(0, Color.White),
                    Tuple.Create(0, Color.White),
                    Tuple.Create(0, Color.White),
                    Tuple.Create(0, Color.White)
                };
            }

            {
                // Skip first entry, as that one's subject to change.
                var i        = 1;
                var incoming = info.IncomingTraffic.First.Next;
                var outgoing = info.OutgoingTraffic.First.Next;
                while (i < info.IncomingTraffic.Count &&
                       incoming != null && outgoing != null)
                {
                    var subTotal = 0;
                    {
                        var val = incoming.Value[TrafficTypes.Any];
                        if (val < minIncoming)
                        {
                            minIncoming = val;
                        }
                        if (val > maxIncoming)
                        {
                            maxIncoming = val;
                        }
                        avgIncoming += val;
                        subTotal    += val;

                        values[i - 1][0] = Tuple.Create(incoming.Value[TrafficTypes.Invalid], Color.Firebrick);
                        values[i - 1][1] = Tuple.Create(incoming.Value[TrafficTypes.Protocol], Color.DarkBlue);
                        values[i - 1][2] = Tuple.Create(incoming.Value[TrafficTypes.Data], Color.Blue);
                    }
                    {
                        int val = outgoing.Value[TrafficTypes.Any];
                        if (val < minOutgoing)
                        {
                            minOutgoing = val;
                        }
                        if (val > maxOutgoing)
                        {
                            maxOutgoing = val;
                        }
                        avgOutgoing += val;
                        subTotal    += val;

                        values[i - 1][3] = Tuple.Create(outgoing.Value[TrafficTypes.Protocol], Color.Green);
                        values[i - 1][4] = Tuple.Create(outgoing.Value[TrafficTypes.Data], Color.LimeGreen);
                    }
                    if (subTotal < minTotal)
                    {
                        minTotal = subTotal;
                    }
                    if (subTotal > maxTotal)
                    {
                        maxTotal = subTotal;
                    }
                    avgTotal += subTotal;

                    ++i;
                    incoming = incoming.Next;
                    outgoing = outgoing.Next;
                }
            }

            avgIncoming /= info.HistoryLength - 1;
            avgOutgoing /= info.HistoryLength - 1;
            avgTotal    /= info.HistoryLength - 1;

            var netInfo = String.Format(
                "in: {0}|{1}|{2}|{3:f2}kB/s\n" +
                "    aps: {12:f2}|apc: {13:f2}\n" +
                "out: {4}|{5}|{6}|{7:f2}kB/s\n" +
                "     aps: {14:f2}|apc: {15:f2}\n" +
                "sum: {8}|{9}|{10}|{11:f2}kB/s",
                minIncoming,
                maxIncoming,
                avgIncoming,
                avgIncoming / 1024f,
                minOutgoing,
                maxOutgoing,
                avgOutgoing,
                avgOutgoing / 1024f,
                minTotal,
                maxTotal,
                avgTotal,
                avgTotal / 1024f,
                info.IncomingPacketSizes.Mean(),
                info.IncomingPacketCompression.Mean(),
                info.OutgoingPacketSizes.Mean(),
                info.OutgoingPacketCompression.Mean());
            var netInfoMeasure  = font.MeasureString(netInfo);
            var netInfoPosition = offset;
            var graphPosition   = new Vector2(offset.X, offset.Y + netInfoMeasure.Y + 5);

            var graphNormX = graphWidth / (float)Math.Max(info.IncomingTraffic.Count, info.OutgoingTraffic.Count);
            var graphNormY = graphHeight / (float)Math.Max(maxTotal, 1);

            // Draw it.
            spriteBatch.Begin();
            spriteBatch.DrawString(font, netInfo, netInfoPosition, Color.White);

            // Draw the bars.
            var barIndex = 0;

            foreach (var bar in values)
            {
                var barX   = (int)(graphPosition.X + barIndex * graphNormX);
                var bottom = graphPosition.Y + graphHeight;
                foreach (var segment in bar)
                {
                    if (segment.Item1 <= 0)
                    {
                        continue;
                    }

                    var top  = (int)(bottom - segment.Item1 * graphNormY);
                    var line = new Rectangle(barX, top, (int)graphNormX, (int)(bottom - top));
                    spriteBatch.Draw(PixelTextures[spriteBatch], line, segment.Item2);
                    bottom = top;
                }
                ++barIndex;
            }

            spriteBatch.End();
        }
示例#8
0
        /// <summary>
        /// Check for addresses ordering.
        /// </summary>
        public static bool IsRange(IReadOnlyCollection <IRegisterGroup> registerGroups, IProtocolInfo info)
        {
            var registerInRangeCount = 0;
            // Already includes first and last registers addresses.
            int dataSize = 2 * info.AddressSize;

            int nextAddress = registerGroups.First().Address;

            foreach (IRegisterGroup registerGroup in registerGroups)
            {
                if (dataSize + registerGroup.DataSize > info.MaxDataLength)
                {
                    break;
                }

                foreach (IRegister register in registerGroup.GetRawRegisters())
                {
                    if (register.Address != nextAddress)
                    {
                        return(false);
                    }

                    nextAddress++;
                    registerInRangeCount++;
                }

                dataSize += registerGroup.DataSize;
            }

            if (registerInRangeCount < info.MinimumRangeRegisterCount)
            {
                return(false);
            }

            return(true);
        }
示例#9
0
        public static byte[] ComposeDataAsSeries(IReadOnlyCollection <IRegisterGroup> registerGroups, IProtocolInfo info, IEnumerable <byte> dataHeader,
                                                 bool withValues, out IReadOnlyCollection <IRegisterGroup> composedGroups)
        {
            var result            = new List <byte>(dataHeader);
            var composedGroupList = new List <IRegisterGroup>();

            int currentDataPacketSize = result.Count;

            foreach (IRegisterGroup registerGroup in registerGroups)
            {
                int groupSize = GetGroupSizeAsSeries(registerGroup, info);

                if (currentDataPacketSize + groupSize > info.MaxDataLength)
                {
                    break;
                }

                currentDataPacketSize += groupSize;

                foreach (IRegister register in registerGroup.GetRawRegisters())
                {
                    result.AddRange(GetRegisterAddress(register.Address, info));

                    if (withValues)
                    {
                        result.AddRange(register.ToBytes());
                    }
                }

                composedGroupList.Add(registerGroup);
            }

            composedGroups = composedGroupList;
            return(result.ToArray());
        }
示例#10
0
        /// <summary>
        /// Range represent sequence of registers ordered by address in row with structure:
        /// first register address, last register address, register 1 value, register 2 value, ..., register n value.
        /// </summary>
        public static byte[] ComposeDataAsRange(IReadOnlyCollection <IRegisterGroup> registerGroups, IProtocolInfo info, IEnumerable <byte> dataHeader,
                                                bool withValues, out IReadOnlyCollection <IRegisterGroup> composedGroups)
        {
            var result            = new List <byte>(dataHeader);
            var composedGroupList = new List <IRegisterGroup>();

            result.AddRange(GetRegisterAddress(registerGroups.First().Address, info));

            int lastRegisterAddressIndex = result.Count;

            // Temp address should be specified after the packet is formed.
            result.AddRange(Enumerable.Repeat <byte>(0, info.AddressSize));

            // Current packet size with last address.
            int currentDataPacketSize = result.Count;

            foreach (IRegisterGroup registerGroup in registerGroups)
            {
                if (currentDataPacketSize + registerGroup.DataSize > info.MaxDataLength)
                {
                    break;
                }

                currentDataPacketSize += registerGroup.DataSize;

                if (withValues)
                {
                    result.AddRange(registerGroup.ToBytes());
                }

                composedGroupList.Add(registerGroup);
            }

            byte[] endRangeAddress = GetRegisterAddress(composedGroupList.Last().GetLastRegisterAddress(), info);
            foreach (int indexOffset in Enumerable.Range(0, info.AddressSize))
            {
                result[lastRegisterAddressIndex + indexOffset] = endRangeAddress[indexOffset];
            }

            composedGroups = composedGroupList;
            return(result.ToArray());
        }
示例#11
0
 private static byte[] GetRegisterAddress(int address, IProtocolInfo info)
 {
     return(LittleEndianConverter.GetBytes(address, info.AddressSize));
 }
示例#12
0
 private static int GetGroupSizeAsSeries(IRegisterGroup registerGroup, IProtocolInfo info)
 {
     return(info.AddressSize + registerGroup.DataSize);
 }
        private static IReadOnlyList <IRegister> ParseAsRange(IReadOnlyList <byte> data, IProtocolInfo info, bool withValues)
        {
            // Ignore gByte.
            int currentByteIndex = info.DataOffset + 1;

            // Bytes after gByte are a range of addresses.
            byte startAddress   = data[currentByteIndex++];
            byte endAddress     = data[currentByteIndex++];
            int  registersCount = endAddress - startAddress + 1;

            // Check addresses validity.
            if (startAddress > endAddress)
            {
                throw new InvalidRegistersException("Wrong register Address");
            }

            // Check registers count is valid number (less than registerGroup values bytes count).
            if (withValues && registersCount > data[info.SizeOffset] - info.MinPacketLength - 2)
            {
                throw new TooMuchDataRequestedException("Wrong data amount");
            }

            var registers = new List <Register <byte> >(registersCount);

            foreach (int address in Enumerable.Range(startAddress, registersCount))
            {
                Register <byte> register = withValues
                    ? Register <byte> .CreateByte(address, RegisterType.Raw, data[currentByteIndex++])
                    : Register <byte> .CreateByte(address, RegisterType.Raw);

                registers.Add(register);
            }

            return(registers);
        }
        private static IReadOnlyList <IRegister> ParseAsSeries(IReadOnlyList <byte> data, IProtocolInfo info, bool withValues)
        {
            // Look through all data bytes except CRC.
            byte packetSize = data[info.SizeOffset];
            int  byteIndex  = info.MinPacketLength;

            var registers = new List <Register <byte> >();

            if (withValues)
            {
                while (byteIndex < packetSize - 1)
                {
                    registers.Add(Register <byte> .CreateByte(data[byteIndex++], RegisterType.Raw, data[byteIndex++]));
                }
            }
            else
            {
                while (byteIndex < packetSize - 1)
                {
                    registers.Add(Register <byte> .CreateByte(data[byteIndex++], RegisterType.Raw));
                }
            }

            // Case of crc is register value.
            if (byteIndex != packetSize - 1)
            {
                throw new Exception("Wrong data amount");
            }

            return(registers);
        }
示例#15
0
 public string ToText(IProtocolInfo info)
 {
     return(JsonConvert.SerializeObject(info));
 }
示例#16
0
        /// <summary>
        /// 验证学生
        /// </summary>
        /// <param name="e"></param>
        /// <param name="info"></param>
        private static bool DoFirstValidation(ClientStateEventArgs e, IProtocolInfo info)
        {
            S2T_ConnectInfo connectInfo = info as S2T_ConnectInfo;

            // 新的客户端
            var ThisClient = e.ClientProxy;
            // 新的学生编号
            var ThisBusinessId = connectInfo.msg.sId;
            // 全局的学生清单
            var StudentDevices = ServerManager.StudentDevices;

            lock (StudentDevices)
            {
                // 查询学生清单中是否存在对应编号的学生
                Student key = StudentDevices.Keys.FirstOrDefault(p => p.StudentBusinessId == ThisBusinessId);
                if (key != null)
                {
                    var ValueClient = StudentDevices[key];
                    if (ValueClient == null)
                    {
                        // 如果不存在,则关联学生对象和客户端对象
                        StudentDevices[key]   = ThisClient;
                        ThisClient.BusinessID = key.StudentBusinessId; // 关联业务ID,以便下次作比较

                        // 2019-04-16 mzc
                        //e.BusinessId = ThisBusinessId;

                        key.IsOnline = true;

                        Console.WriteLine($"学生{key.RealName}连接上了");
                    }
                    else
                    {
                        // 如果已存在,判断客户端列表里是否有相同ID的连接(比较业务ID,如果相同,则断开之前的连接)
                        if (ValueClient.BusinessID.ToDefaultString() == ThisBusinessId)
                        {
                            var lastClient = StudentDevices[key];

                            //todo: 改为发命令
                            //ServerManager.Recycle(lastClient.ReceiveContext);

                            Console.WriteLine("同一学生重复连接,回收之前的一个连接,并保留当前连接。");
                        }

                        StudentDevices[key]   = ThisClient;
                        ThisClient.BusinessID = key.StudentBusinessId;

                        key.IsOnline = true;


                        // 2019-04-16 mzc
                        //e.BusinessId = ThisBusinessId;
                    }

                    return(true);
                }
                else
                {
                    // 如果连接上来的不是该班级的学生,则断开连接
                    ServerManager.Recycle(e.ClientSocketContext);

                    return(false);
                }
            }
        }