public IServerMessage BuildServerMessage(IChannel channel, string user, string message)
        {
            var resultCommand = new ServerMessage();
            resultCommand.Id = (uint)DiContainer.Container.Resolve<IInternalIdCounter>().Id;
            resultCommand.Channel = channel;
            resultCommand.CommandType = Enums.CommandType.Undefined;
            resultCommand.MessageType = Enums.MessageType.Message;
            resultCommand.User = user;

            var optionsHeader = "<options>";
            optionsHeader += "<id>" + resultCommand.Id + "</id>";
            optionsHeader += "<messageType>" + Convert.ToInt32(resultCommand.MessageType) + "</messageType>";
            optionsHeader += "<command>" + Convert.ToInt32(resultCommand.CommandType) + "</command>";
            optionsHeader += "<channel>" + resultCommand.Channel.Name + "</channel>";
            optionsHeader += "<user>" + user + "</user>";
            optionsHeader += "</options>";

            var commandMessage = "<message>" + message + "</message>";

            var optionsBytes = System.Text.Encoding.UTF8.GetBytes(optionsHeader);
            resultCommand.OptionsSize = (uint)optionsBytes.Count();

            var messageBytes = System.Text.Encoding.UTF8.GetBytes(commandMessage);
            resultCommand.ContentSize = (uint)messageBytes.Count();

            var optionsByteSize = BitConverter.GetBytes(resultCommand.OptionsSize);
            var messageByteSize = BitConverter.GetBytes(resultCommand.ContentSize);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(optionsByteSize, 0, optionsByteSize.Length);
                Array.Reverse(messageByteSize, 0, messageByteSize.Length);
            }

            resultCommand.SerializedMessage = ConcatBytes(ConcatBytes(optionsByteSize, messageByteSize), ConcatBytes(optionsBytes, messageBytes));

            return resultCommand;
        }
예제 #2
0
        private void SocketListener()
        {
            while (_connectionActive && _client.Connected)
            {
                if (_client.GetStream().DataAvailable)
                {
                    // Read Data from stream
                    var optionsSizeBuffer = new byte[4];
                    var contentSizeBuffer = new byte[4];

                    _client.GetStream().Read(optionsSizeBuffer, 0, 4);
                    _client.GetStream().Read(contentSizeBuffer, 0, 4);

                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(optionsSizeBuffer, 0, optionsSizeBuffer.Length);
                        Array.Reverse(contentSizeBuffer, 0, contentSizeBuffer.Length);
                    }

                    var optionsSize = (uint)BitConverter.ToInt32(optionsSizeBuffer, 0);
                    var contentSize = (uint)BitConverter.ToInt32(contentSizeBuffer, 0);

                    var optionsBuffer = new byte[optionsSize];
                    var contentBuffer = new byte[contentSize];

                    // Dirty typecast (OH NOEZ)
                    _client.GetStream().Read(optionsBuffer, 0, (int)optionsSize);
                    _client.GetStream().Read(contentBuffer, 0, (int)contentSize);

                    var optionsText = System.Text.Encoding.UTF8.GetString(optionsBuffer);
                    var contentText = System.Text.Encoding.UTF8.GetString(contentBuffer);

                    var optionsDoc = new XmlDocument();
                    optionsDoc.LoadXml(optionsText);
                    var contentDoc = new XmlDocument();
                    contentDoc.LoadXml(contentText);

                    var resultMessage = new ServerMessage();
                    try
                    {
                        resultMessage.Id = Convert.ToUInt32(optionsDoc.SelectSingleNode(@"/options/id").InnerText);
                        resultMessage.MessageType = (Enums.MessageType)Convert.ToInt32(optionsDoc.SelectSingleNode(@"/options/messageType").InnerText);
                        var commandInnerText = optionsDoc.SelectSingleNode(@"/options/command").InnerText;
                        if (!string.IsNullOrEmpty(commandInnerText)) resultMessage.CommandType = (Enums.CommandType)Convert.ToUInt32(commandInnerText);
                        var channelName = optionsDoc.SelectSingleNode(@"/options/channel").InnerText;
                        var existingChannels = KnownChannels.Where(p => p.Name == channelName);

                        if (existingChannels.Any())
                            resultMessage.Channel = existingChannels.First();
                        else
                        {
                            var channel = new Channel() { IsOpened = false, Name = channelName, MessageLog = new MessageLog() };
                            resultMessage.Channel = channel;
                            KnownChannels.Add(channel);
                        }

                        resultMessage.User = optionsDoc.SelectSingleNode(@"/options/user").InnerText;
                        resultMessage.MessageContent = contentDoc.SelectSingleNode(@"/message").InnerText;
                        resultMessage.OptionsSize = optionsSize;
                        resultMessage.ContentSize = contentSize;
                    }
                    catch(Exception ex)
                    {
                        // Corrupt document -- ignore
                        DiContainer.Container.Resolve<ILoggingManager>().LogError("An error occurred while trying to parse response document from server.", ex);
                    }

                    IncomingMessages.Add(resultMessage);

                    foreach (var subscriber in _subscribers)
                    {
                        subscriber.OnServerMessageReceived();
                    }
                }
                Thread.Sleep(100);
            }
        }