silverlightwcf:Silverlight专题(10)-WCF通信(2)

  在上文我粗略介绍了如何创建WCF Service并在客户端生成WCF Service来取得数据

  问题:  WCF Service时候并没有个DownloadProcessChanged的类事件来反馈已经上传了多少

  那么我们如何来实现在客户端实时展示当天已经上传了多少呢?

  解决方案:  我们可以把文件分成很多块逐次上传小部分(比如2K4K8K等等)

  1首先我们还是按照Silverlight专题(9)-WCF通信(1)这个教程中所示先创建个新Silverlight工程

  并添加进个Silverlight-Enabled WCF Service(我取名为DownloadService以前随便去名字懒得改了)

  其里面含有操作契约如下:

1 [ServiceContract(Namespace = "")]
2 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
3 public DownloadService
4 {
5   [OperationContract]
6   public UploadImg( fileName, fileData, bool firstChunk, bool lastChunk)
7   {
8     (!File.Exists(@HostingEnvironment.ApplicationPhysicalPath + @"/Uploads/" + fileName))
9     {
10       tmpExtension = "_tmp";
11       tempFileName = fileName + tmpExtension;
12       (firstChunk)
13       {
14         fileName tmpExtension;
15         (File.Exists(@HostingEnvironment.ApplicationPhysicalPath + tempFileName))
16         {
17           File.Delete(@HostingEnvironment.ApplicationPhysicalPath + tempFileName);
18         }
19       }
20 
21       FileStream fs = File.Open(@HostingEnvironment.ApplicationPhysicalPath + tempFileName, FileMode.Append);
22       fs.Write(fileData, 0, fileData.Length);
23       fs.Close;
24 
25       (lastChunk)
26       {
27         //Rename file to original file
28         File.Move(@HostingEnvironment.ApplicationPhysicalPath + tempFileName, @HostingEnvironment.ApplicationPhysicalPath + "/ClientBin/Uploads/" + fileName);
29       }
30     }
31 
32     "./Uploads/" + fileName;
33   }
34 }


  Upload这个操作契约输入参数有文件名文件比特firstChunk用来表示是否传输是文件个包

  lastChunk代表文件包是不是最后个包

  如果还不是最后个包时将传输过来文件文件扩展名加上后缀_tmp来存放

  旦lastChunk为true时将该文件存为原文件名

  2.实现客户端界面

  我们需要 3个东西

  个用来选择上传文件对话框Button

  个用来展示上传进度进度条

  个用来展示结果ImageControl控件

  (我设置为只能上传JPG或者PNG文件结果返回个上传后图片相对路径)

  代码如下:

1 <UserControl x:Class="ReadImageTest.Page"
2   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
3   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
4   <StackPanel x:Name="LayoutRoot" Background="#3C3C3C">
5     <Grid>
6       <Image x:Name="img" Width="800" Height="600"/>
7       <ProgressBar x:Name="pb" Height="20" Width="400" Maximum="1" Visibility="Collapsed"/>
8     </Grid>
9     <Button Margin="0,5" x:Name="uploadBtn" Content="Upload" Padding="8,4" FontSize="15" HorizontalAlignment="Center" Click="uploadBtn_Click"/>
10   </StackPanel>
11 </UserControl>
3.具体底层控制代码

  a.选择上传文件对话框实现如下

1 public void uploadBtn_Click(object sender, RoutedEventArgs e)
2 {
3   OpenFileDialog ofd = OpenFileDialog;
4   ofd.Filter = "JPG Files|*.jpg|PNG Files|*.png";
5   ofd.Multiselect = false;
6 
7   ((bool)ofd.ShowDialog)
8   {
9     this.pb.Visibility = Visibility.Visible;
10     this.img.Opacity = 0;
11     dataSent = 0;
12     stream = ofd.File.OpenRead;
13     dataLength = stream.Length;
14     (dataLength > 16384)
15     {
16       firstChunk = true;
17       lastChunk = false;
18       fileName = ofd.File.Name;
19       buffer = [4 * 4096];
20       read = stream.Read(buffer, 0, buffer.Length);
21       dataSent read;
22       (read != 0)
23       {
24         (dataSent dataLength)
25           lastChunk = true;
26         client.UploadImgAsync(fileName, buffer, firstChunk, lastChunk);
27         firstChunk = false;
28       }
29     }
30 
31    
32     {
33       MessageBox.Show("The upload file is too small!");
34     }
35   }
36 }


  我设置了每个包大小是16K

  也就是每次WCF Service最多只能传16K东西

  BTW:其中Client定义为 private DownloadServiceRef.DownloadServiceClient client;

  b.展示上传进度并显示最终上传结果

1void client_UploadImgCompleted(object sender, ReadImageTest.DownloadServiceRef.UploadImgCompletedEventArgs e)
2{
3   (dataSent < dataLength)
4  {
5     buffer = [4 * 4096];
6     read = stream.Read(buffer, 0, buffer.Length);
7    dataSent read;
8    this.pb.Value = (double)dataSent / dataLength;
9     (read != 0)
10    {
11       (dataSent dataLength)
12        lastChunk = true;
13      client.UploadImgAsync(fileName, buffer, firstChunk, lastChunk);
14      firstChunk = false;
15    }
16  }
17
18  
19  {
20    this.pb.Visibility = Visibility.Collapsed;
21    this.img.Opacity = 1;
22    this.img.Source = BitmapImage( Uri(e.Result, UriKind.RelativeOrAbsolute));
23  }
24}


  每上传完个包就更新下上传进度条

  如果传送大小已经等于文件大小时隐藏进度条并展示上传图片

  整理总结:  Silverlight目前对WCF支持虽然只局限在普通HttpBinding但是功能也还算强大

  本文只是小试牛刀展示了个小小图片上传工具实现希望能起到抛砖引玉作用

Tags:  silverlight.2.0 silverlight是什么 silverlight silverlightwcf

延伸阅读

最新评论

发表评论