locked
Sync files between mobile device and server RRS feed

  • Question

  • Hi all,

    I have been searching for an answer for almost three days now and can't seem to get it. I've tried many different ways but need some help to do this right.

    My scenario:
    Users capture data on a simple Web application that uses XML as a data store. They can also upload images which is referenced in the XML but resides on the server's file system.

    Users can then continue their data capturing in the field using a mobile device.

    The challenge I am faced with is the best way to transfer the XML files and images to the mobile device and then back to the server.
    I am using web services, which works well until the file size exceeds 10MB or so, when I get a OutOfMemoryException on the device. The way I am transferring data is based on a sample that I got from the web, code snippets below.

    [WebMethod]  
        public XmlNode DonwloadFile(string serverFileName)  
        {  
            FileInfo file = new FileInfo(serverFileName);  
            if (file.Exists)  
            {  
                string[] myFiles = new String[1];  
                myFiles[0] = file.FullName;  
                return SendFiles.GetFileXml(myFiles);  
            }  
     
            return null;  
        }  
     
     
    public static XmlDocument GetFileXml(String[] Files)  
            {  
                //We are returning an XML Doc  
                XmlDocument tmpXmlDoc = new XmlDocument();  
                //Create the root node...  
                tmpXmlDoc.LoadXml("<Files></Files>");  
     
                //Loop through the WorkItemFiles array and create the file nodes  
                for (Int32 i = 0; i <= Files.Length - 1; i++)  
                {  
                    //The File node  
                    XmlElement tmpFile = tmpXmlDoc.CreateElement("File");  
                    //Add the filename attribute to it...  
                    XmlAttribute tmpA = tmpXmlDoc.CreateAttribute("FileName");  
                    //Find the last \ to pull off the filename.  
                    tmpA.Value = Files[i].Substring(Files[i].LastIndexOf(@"\") + 1);  
                    tmpFile.Attributes.Append(tmpA);  
     
                    //Read in the File  
                    Byte[] myCompressed;  
     
                    //Compress the file  
                    myCompressed = CompressionHelper.CompressFile(Files[i]);  
     
                    //Next encode the compressed stream so that we don't blow the CData node in the XML     
                    Char[] myEncoded;  
                    Base64Encoder myBE;  
                    myBE = new Base64Encoder(myCompressed);  
                    myEncoded = myBE.GetEncoded();  
     
                    //A StringBuilder is the fastest way to get a string from a byte array  
                    StringBuilder myStr = new StringBuilder();  
                    myStr.Append(myEncoded);  
     
                    //create CData child appened to the file node...  
                    tmpFile.AppendChild(tmpXmlDoc.CreateCDataSection(myStr.ToString()));  
     
                    //Add the file node to the xml doc...  
                    tmpXmlDoc.DocumentElement.AppendChild(tmpFile);  
                } // for  
     
                return tmpXmlDoc;  
            }  
     
     
     
     
    public static byte[] CompressFile(string filePath)  
            {  
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))  
                using (BinaryReader r = new BinaryReader(fs))  
                {  
                    byte[] buf = new byte[fs.Length];  
                    r.Read(buf, 0, (int)fs.Length);  
     
                    return CompressBytes(buf);  
                }  
            }  
     


    As you can see, I even compress the data and this works, but not for large files.

    Like I said, I have searched quite a bit and found examples using MTOM over web services, which I couldn't get working on Compact FrameWork 3.5. Then I looked at OpenNetCF FTP, and the example I found was unstable, couldn't get it stable, I looked at WCE, WCF and now I'm at Sync FrameWork.

    Then I found Bryant Likes' example (http://blogs.sqlxml.org/bryantlikes/archive/2008/01/03/remote-file-sync-using-wcf-and-msf.aspx) which looked really promising because the Sync FrameWork would actually handle a lot of logic I have to code myself at the moment. But... I couldn't get it working, even when downgrading and using Microsoft.Synchronization version 0.94.0.0, I got errors, for example ChangeBatchBuilder does not exist, etc.

    I am at the point of gicing up because Microsoft doens't seem to have a definite guideline or framework to do this. All I need is a simple mechanism to upload files from a mobile device to a web server and to download files form the server to the device. (Preferrably chunked so I can handle large files and connection drops)

    Should I use, FTP, Web Services, WCE, WCF, Sync FrameWork or some other technology? Nobody seems to really know or I am unable to find Microsoft's view on this, code samples will of course be great to help ease the frustration of trying to get the stuff to work. (Especially WCF on mobile device, what a mission!)

    Technologies used:
    Visual Studio 2008 SP1
    .NET 3.5 SP1
    Compact FrameWork 3.5 (Windows Mobile 6)

    If anybody can give me advise here or point me in the right direction, I will be very grateful, I have spent many days and very late nights trying different options with no luck.

    Thanks

    • Moved by Max Wang_1983 Thursday, April 21, 2011 5:28 PM forum consolidation (From:SyncFx - Technical Discussion [ReadOnly])
    Sunday, February 8, 2009 9:03 PM

Answers

  • The Sync Framework will help you for all things "sync": change detection, conflict detection, ... MSF can be used on top of any transport but MSF is not a transport itself. 

    Based on the description of your scenario I think that both FTP or WCF are good candidates for transfering your files. My guess is that the OutOfMemory exception your seeing is probably related to the buffer sizes used by the server or the client. Also I know that WCF has a "streaming" mode that could be useful for files.  Please refer to the WCF docs on msdn for more information.
    Jeremie (Microsoft Sync Framework)
    Saturday, February 14, 2009 1:28 AM

All replies

  • The Sync Framework will help you for all things "sync": change detection, conflict detection, ... MSF can be used on top of any transport but MSF is not a transport itself. 

    Based on the description of your scenario I think that both FTP or WCF are good candidates for transfering your files. My guess is that the OutOfMemory exception your seeing is probably related to the buffer sizes used by the server or the client. Also I know that WCF has a "streaming" mode that could be useful for files.  Please refer to the WCF docs on msdn for more information.
    Jeremie (Microsoft Sync Framework)
    Saturday, February 14, 2009 1:28 AM
  • Just want to point out that, WCF on Compact Framework 3.5 does not support streaming messages and is limited to the TextMessageEncoder using BasicHttpBinding. Check the following link for the limitations of WCF on CF 3.5:
    http://blogs.msdn.com/andrewarnottms/archive/2007/08/21/the-wcf-subset-supported-by-netcf.aspx
    Thursday, April 23, 2009 1:54 PM