2011-05-02 43 views
2

我有一個應用程序在MSMQ消息隊列中顯示消息的內容。 Windows 7上的MSMQ存在一個問題,它不保留消息正文中數據的真實對象類型。在這個例子中,我發送了一個字節[],然後當我收到它時,它不再是一個字節數組,而是包裝的XML容器文檔。在Windows XP中,我從來沒有遇到過這個問題,並且Message.Body屬性總是正確設置爲byte []。MSMQ + C#,接收帶編碼字節[]體的消息在Windows 7與Windows XP上的行爲有所不同

這裏是壓縮代碼:

public void SendWithCompression(string Message) 
    { 
     try 
     { 
      // Compress the message data in memory. 
      byte[] UncompressedData = Encoding.UTF8.GetBytes(Message); 
      byte[] CompressedData = null; 

      MemoryStream s = new MemoryStream(); 
      using (GZipStream z = new GZipStream(s, CompressionMode.Compress)) 
      { 
       z.Write(UncompressedData, 0, UncompressedData.Length); 
      } 
      CompressedData = s.ToArray(); 

      if (_Transaction != null) 
      { 
       _Transaction.Begin(); 
       base.Send(CompressedData, _Transaction); 
       _Transaction.Commit(); 
      } 
      else 
      { 
       base.Send(CompressedData); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

下面是測試消息的消息內容。它結束了作爲一個包裝編碼的二進制數據: <?xml version="1.0"?>..<base64Binary>H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ih63edMefTsvy2rv8V3+4/8ByygBlxMAAAA=</base64Binary>


這裏是它使用的解壓縮代碼的XML文檔:

 String Data; 
     //Get message and format XML 
     System.Messaging.Message m = MessagesList[ListIndex].Tag; 
     m.Formatter = new XmlMessageFormatter(new Type[] 
     { 
      typeof(string), // Send raw plain strings 
      typeof(byte[]), // Array of binary data 
      typeof(XmlNode) // Xml document 
     }); 

     m.BodyStream.Position = 0; 

     Data = m.Body.ToString(); 
      if (m.Body.GetType() == typeof(byte[])) 
      { 
       try 
       { 
        // The message body is an array of binary data. 
        // Assume it is a GZIP stream of compressed data. 
        byte[] CompressedData = (byte[])m.Body; 
        byte[] UncompressedData = null; 

        // Decompress it. 
        MemoryStream s = new MemoryStream(CompressedData); 
        using (GZipStream z = new GZipStream(s, CompressionMode.Decompress)) 
        { 
         UncompressedData = MyExtensions.ReadRemainingBytes(z); 
        } 

        // Turn the bytes back into a string. 
        Data = Encoding.UTF8.GetString(UncompressedData); 
       } 
       catch 
       { 
        Data = "Unknown binary data: " + 
        BitConverter.ToString((byte[])m.Body, 0); 
       } 
      } 
      if (m.Body.GetType() == typeof(XmlElement)) 
      { 
       XmlElement el = (XmlElement)m.Body; 
       if (el.Name == "string") 
        Data = el.InnerText; 
       else 
        Data = el.OuterXml; 
      } 

我想指出,我我正在設置消息的格式化程序,這是讓身體在隊列中自動「框」和「開箱」的第一步。

在Windows XP中,m.Body.GetType()== byte [],如預期的那樣。但是,在Windows 7中,m.Body.GetType()== XmlElement,即包裝器XML。它不再「解開」信息。

我們需要做不同的事情嗎?我們已經爲它發送了一次字符串,就像你在接收函數結束時看到的一樣,但是我想找到一個真正的答案,說明爲什麼這個代碼在Windows 7上表現不同。

+0

從XmlMessageFormatter構造函數調用中移除XmlNode。 – 2011-05-03 00:32:57

回答

7

使用Message.BodyStream財產,如果要發送的字節數組:用於發送和接收消息

System.Messaging.MessageQueue queue = new MessageQueue(queueFormatName, false, true, QueueAccessMode.Send); 

System.Messaging.Message msg = new System.Messaging.Message(); 
msg.BodyStream = new MemoryStream(buffer); 

queue.Send(msg, MessageQueueTransactionType.Single); 
2

使用Message.BodyStream財產,看看下面的代碼,你可以發送和使用它接收byte[]

public void SendMessage() 
{ 
    MessageQueue myQueue = new MessageQueue(".\\QUEUE"); 
    byte[] msg = new byte[2]; 
    msg[0] = 29;    
    // Send the array to the queue. 
    Message msg1 = new Message(); 
    msg1.BodyStream = new MemoryStream(msg); 
    messageQueue.Send(msg1);     
} 

public void ReceiveMessage() 
{ 
    MessageQueue myQueue = new MessageQueue(".\\QUEUE");    
    Message myMessage =myQueue.Receive(); 
    byte[] msg = ReadFully(myMessage.BodyStream); 
} 

public static byte[] ReadFully(Stream input) 
{ 
    byte[] buffer = new byte[16 * 1024]; 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     int read; 
     while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      ms.Write(buffer, 0, read); 
     } 
     return ms.ToArray(); 
    } 
} 
相關問題