Silverlight與WCF通信(二) :Silverlight通過netTcpBinding訪問IIS宿主WCF


   本篇我們介紹Silverlight通過net.Tcp方式訪問IIS宿主的WCF。

   Windows (Process) Activation Service (簡稱:WAS  全稱:Windows 進程激活服務)是 IIS7.0 特有的新增功能,比IIS6 的功能更加強大,它提供並支持除HTTP之外的更多協議。由於Net.tcp 協議在 Silverlight 中的不支持傳輸層安全性,我們盡量在安全性比較好的Intranet 環境中使用此傳輸方式。

   本例子的開發環境是:Win7旗艦版+VS2010+Silverlight4+IIS7。項目代碼和結構和上一篇一樣,WCF服務代碼沒有任何改變,只不過是WcfHost.web 中的Web.Config 中配置代碼進行了改變,為了方便查看,我再貼一下項目結構和代碼:

項目結構(如圖):

代碼實現:

類庫LxContracts:(包括數據契約Student.cs和操作契約IStudent.cs)

Student.cs 代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace LxContracts
{
    [DataContract]
    public class Student
    {
        /// <summary>
        /// 學生編號
        /// </summary>
        [DataMember]
        public int StuId { get; set; }

        /// <summary>
        /// 學生姓名
        /// </summary>
        [DataMember]
        public string StuName { get; set; }

        /// <summary>
        /// 所在班級
        /// </summary>
        [DataMember]
        public string ClassName { get; set; }

        /// <summary>
        /// 聯系電話
        /// </summary>
        [DataMember]
        public string TelPhoneNum { get; set; }
    }
}
IStudent.cs 代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace LxContracts
{
    [ServiceContract]
    public interface IStudent
    {
        [OperationContract]
        List<Student> GetStudent();
    }
}

類庫LxServices:( 改類庫包括一個模仿獲取數據庫集合類StudentList.cs和服務類StudentService.cs)

StudentList.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LxContracts
{
    public class StudentList:List<Student>
    {

        public StudentList()
        {
            this.Add(new Student() { StuId = 1, StuName = "小明", ClassName = "計算機一班", TelPhoneNum = "123456" });
            this.Add(new Student() { StuId = 2, StuName = "小紅", ClassName = "計算機二班", TelPhoneNum = "234567" });
            this.Add(new Student() { StuId = 2, StuName = "小蘭", ClassName = "計算機三班", TelPhoneNum = "890123" });
        }
    }
}
StudentService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using LxContracts;

namespace LxServices
{
    public class StudentService:IStudent
    {
        public List<Student> GetStudent()
        {
            //實際情況應該為從數據庫讀取
            //本例手動生成一個StudentList
            StudentList ListStuent = new StudentList();
            return ListStuent;
        }
    }
}

站點WcfHost.web

站點WcfHost.web,這是一個Asp.net 空web應用程序。

1、右擊” WcfHost.web”—“添加”—“新建項”—“wcf服務”,命名為”StudentSrv.svc” 。如圖:

在項目中刪除”StudentSrv.svc.cs”文件和”IStudentSrv.cs”文件。右擊”StudentSrv.svc”文件,選擇”查看標記”,將代碼修改為:

<%@ ServiceHost Language="C#" Service="LxServices.StudentService" %>

 2、修改webconfig 文件,代碼如下:(配置文件和第一篇http方式 發生了改變)

WebConfig
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="LxBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    
    <!--這個必須寫,Silverlight不支持具有安全性的 NetTcpBinding,寫了之后,客戶端引用就變成了CustomBinding-->
    <bindings>
      <netTcpBinding>
        <binding name="myTcpBinding">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service name="LxServices.StudentService" behaviorConfiguration="LxBehavior">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="myTcpBinding" contract="LxContracts.IStudent" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    
    <!--關閉 ASP.NET 兼容性模式-->
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  
  <!--設置默認頁面為StudentSrv.svc-->
  <system.webServer>
    <defaultDocument>
      <files>
        <remove value="default.aspx" />
        <remove value="iisstart.htm" />
        <remove value="index.html" />
        <remove value="index.htm" />
        <remove value="Default.asp" />
        <remove value="Default.htm" />
        <add value="StudentSrv.svc" />
      </files>
    </defaultDocument>
  </system.webServer>
</configuration>

   注意:(1) 配置文件中把 <serviceMetadata httpGetEnabled="false" /> 設置成了false;<service>節點中也去掉了 basicHttpBinding方式的Endpoint,目的是我們的服務元節點地址和傳輸方式只提供net.Tcp方式的。當然也可以不用去掉,這樣服務就提供兩種通道了。(2)netTcp方式 必須增加元數據發布節點mex,因此wcf的服務元數據地址就是:net.tcp://localhost:端口號/StudentSrv.svc/mex

部署服務:

1、添加必要的組件:

    1)打開 “控制面板”—“程序和功能”—“打開或關閉Windows功能”。節點“Microsoft .Net Framework 3.5.1 ”下面的兩項WCF Http 激活和WCF No Http 激活都必須安裝。如下圖:

        

    2)安裝IIS6兼容性和管理工具:

        

    3)查看服務:確保服務Net.Tcp Listener Adapter、Windows Process Activation Service和World Wide Web Publishing Service 都已經啟動。

2、在IIS7中進行部署:

   1)打開IIS7,右擊”應用程序池—“添加應用程序池。名稱輸入為:”WcfTcpPool”,Framework版本選擇為:4.0,如下圖:

       

   2)右擊網站—“添加網站”;網站名稱為:WcfTcpWeb;應用程序池選擇我們剛剛創建的”WcfTcpPool”;物理路徑選擇我們項目下的WcfHost.web的所在路徑;http端口我選擇的是7070,如下圖:

       

   3)選擇我們剛剛創建的網站,在IIS最右面的操作列表中,選擇”高級設置”;在”已啟用的協議” 中輸入 net.tcp ,每個協議之間用 逗號 分隔,如下圖:

       

   4)為網站添加綁定:右擊WcfTcpWeb網站—“編輯綁定”,添加綁定,選擇”net.tcp” ,綁定信息輸入“4505:*”,如下圖:

       

     注意:Silverlight 只能訪問介於45024534范圍之間的端口。

   5)右擊我們的網站,選擇”管理網站”—“瀏覽”;瀏覽器會顯示如下信息:(我們的服務配置已經成功)

      

在Silverlight中進行調用:

1、為Silverlight程序添加WCF:

  “右擊”—“SiverlightDemo”—“添加服務引用”—“輸入服務地址”net.tcp://localhost:4505/StudentSrv.svc/mex --點擊“前往”,就會找到服務,命名為”WCF.StudentSrv”后,點擊”確定”。  

   

2、在Silverlight中調用WCF:(以下代碼跟第一篇實例一樣,為了查看方便我又貼了一下)

MainPage.xaml中添加”DataGrid”控件。

MainPage.xaml 代碼
<sdk:DataGrid x:Name="dgStudnet" Grid.Row="0" AutoGenerateColumns="False">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="學生編號" Width="80" Binding="{Binding StuId}" />
                <sdk:DataGridTextColumn Header="學生姓名" Width="100" Binding="{Binding StuName}" />
                <sdk:DataGridTextColumn Header="所在班級" Width="120" Binding="{Binding ClassName}" />
                <sdk:DataGridTextColumn Header="電話號碼" Width="100" Binding="{Binding TelPhoneNum}" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
MainPage.cs 代碼
namespace SilverlightDemo
{
    public partial class MainPage : UserControl
    {
        ObservableCollection<Student> listStudent;
        public MainPage()
        {
            InitializeComponent();
            listStudent = new ObservableCollection<Student>();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            StudentClient proxyClient = new StudentClient();
            proxyClient.GetStudentAsync();
            proxyClient.GetStudentCompleted += new EventHandler<GetStudentCompletedEventArgs>(proxyClient_GetStudentCompleted);
        }

        void proxyClient_GetStudentCompleted(object sender, GetStudentCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                listStudent = e.Result;
                this.dgStudnet.ItemsSource = listStudent;
            }
        }
    }
}

 3、運行:右擊 "SilverlightDemo" ,選擇“調試”--“啟動新實例”,會產生以下異常信息:

 這還是跨域問題,怎么解決呢?當然還是需要跨域文件(clientaccesspolicy.xml)了,但這個跨域文件和上一篇http綁定方式的跨域文件內容有所不同,放置的位置也有所不同。

clientaccesspolicy.xml 代碼
<?xml version="1.0" encoding="utf-8"?> 
<access-policy> 
   <cross-domain-access> 
      <policy> 
         <allow-from http-request-headers="*"> 
            <domain uri="*" /> 
         </allow-from> 
         <grant-to> 
            <socket-resource port="4502-4534" protocol="tcp" /> 
            <resource path="/" include-subpaths="true"/> 
         </grant-to> 
      </policy> 
   </cross-domain-access> 
</access-policy>

 但是這個跨域文件放到哪里呢?

 netTcp方式的跨域文件並不是放到我們項目中宿主wcf的網站WcfHost.web的根目錄,而是放到IIS 80端口網站的根目錄。我計算機IIS下80端口的網站是Default Web Site,因此放到此網站根目錄下面:

 再次運行我們的Silverlight 程序,會發現WCF調用成功,第一次運行有點慢,耐心等待一下,結果如下圖:

至此,本篇主要介紹了Silverlight和WCF基於net.tcp 方式傳輸的配置及說明,下一篇我們利用Silverlight和WCF實現一個全雙工通信的例子。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM