silverlight+WCF的net.tcp雙工通訊實例過程

silverlight+WCF的net.tcp雙工通訊實例過程html

注:本人只是一個菜鳥,有什麼不對的,請各位大俠指正,成分感謝!!!web

本實例實現一個簡單的單用戶對單用戶的消息發送實例。實例開始:express

  1. 進行net.tcp雙工通訊必須安裝Windows功能下的Microsoft.NET.Framework3.5.1下面兩項
  2. 項目結構以下:

         

說明:SilverlightApp silverlight項目,其網頁承載與WCF服務是一個WEB項目,即WcfService跨域

      WcfContract 一個類庫項目,用於定義契約,需引用System.ServiceModel瀏覽器

      WcfModel一個類庫項目,用於定義數據實體類,須要引用System.Runtime.Serialization服務器

WcfService 一個web項目,用於IIS寄存WCFdom

  1. 新建一個解決方案命名爲nettcpTest
  2. 在解決方案上添加一個類庫項目:WcfModel,在此類庫項目中添加兩個類UserInfo、MessageInfo 。

UserInfos.cssocket

namespace WcfModeltcp

{工具

    [DataContract]

    public class UserInfo

    {

        [DataMember]

        public int Id { get; set; }

        [DataMember]

        public string Name { get; set; }

    }

}

 

MessageInfo.cs

 

namespace WcfModel

{

    [DataContract]

    public class MessageInfo

    {

        [DataMember]

        public UserInfo FromUser { get; set; }

        [DataMember]

        public UserInfo ToUser { get; set; }

        [DataMember]

        public string Content { get; set; }

        [DataMember]

        public DateTime SendTime { get; set; }

    }

}

右鍵此項目,生成。

 

  1. 右鍵解決方案添加一個名爲WcfContract的類庫項目,引用WcfModel,在項目中添加兩個接口:IMessageCallBack、IMessageManage

 

IMessageCallBack.cs

namespace WcfContract

{

    public interface IMessageCallBack

    {

        [OperationContract(IsOneWay = true)]

        void GetMessage(MessageInfo message);

    }

}

IMessageManage.cs

namespace WcfContract

{

    [ServiceContract(CallbackContract = typeof(IMessageCallBack))]

    public interface IMessageManage

    {

        [OperationContract]

        bool SendMessage(MessageInfo msg);

        [OperationContract]

        bool RequestMessage(UserInfo user);

    }

}

右鍵此項目生成。

 

  1. 在解決方案上添加一個空的web項目,名稱爲WcfService,並引用前兩個類庫。而且添加一個WCF服務命名爲MessageService.svc,刪除原有的接口,後臺代碼以下:

MessageService.cs

namespace WcfService

{

    // 注意: 使用「重構」菜單上的「重命名」命令,能夠同時更改代碼、svc 和配置文件中的類名「MessageService」。

    // 注意: 爲了啓動 WCF 測試客戶端以測試此服務,請在解決方案資源管理器中選擇 MessageService.svc 或 MessageService.svc.cs,而後開始調試。

    public class MessageService :IMessageManage

    {

        //用於記錄用戶與對應的通道

        private static Dictionary<int, IMessageCallBack> DicCallChannel = new Dictionary<int, IMessageCallBack>();

        //記錄間用戶的ID

        private int UserId = 0;

 

        public bool SendMessage(WcfModel.MessageInfo msg)

        {

            //獲取對應要發送的通道,回調

            if (DicCallChannel.Keys.Contains(msg.ToUser.Id))

            {

                DicCallChannel[msg.ToUser.Id].GetMessage(msg);

                return true;

            }

            return false;

        }

 

        public bool RequestMessage(WcfModel.UserInfo user)

        {

            //獲取用戶請求創建的通道

            IMessageCallBack channel = OperationContext.Current.GetCallbackChannel<IMessageCallBack>();

            if (!DicCallChannel.Keys.Contains(user.Id))

            {

                DicCallChannel.Add(user.Id, channel);

                UserId = user.Id;                

                OperationContext.Current.Channel.Closing += Channel_Closing;

            }

            return true;

        }

        //當用戶通道關閉時,把用戶的通道記錄刪除,即不記錄已經斷開的通道

        void Channel_Closing(object sender, EventArgs e)

        {

            if (DicCallChannel.Keys.Contains(UserId))

            {

                DicCallChannel.Remove(UserId);

            }

        }

    }

}

 

  1. 打開web.config,添加以下節點

 <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior name="mBehavior">

          <serviceMetadata httpGetEnabled="false" />

          <serviceDebug includeExceptionDetailInFaults="true" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <bindings>

      <netTcpBinding>

        <binding name="mBinding">

          <security mode="None" />

        </binding>

      </netTcpBinding>

    </bindings>

    <services>

      <service name="WcfService.MessageService" behaviorConfiguration="mBehavior">

        <endpoint address="" binding="netTcpBinding" bindingConfiguration="mBinding" contract="WcfContract.IMessageManage" />

        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />

      </service>

    </services>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

  </system.serviceModel>

    <system.webServer>

        <directoryBrowse enabled="true" />

</system.webServer>

右鍵生成些項目

  1. 打開IIS管理器,若是IIS沒有安裝.net4.0,則IIS須要註冊net4.0,怎麼註冊,你們問度娘吧

 

右擊應用程序池,添加應用程序池,命名爲WcfNetTcp,版本選擇.net framework v4.0.30319

 

 

  1. 右擊網站 ,添加網站,網站名爲WcfNetTcp,程序池選擇WcfNetTcp,物理路徑選擇剛剛解決方案中WEB項目WcfService的物理路徑,端口我這裏設置的是8081

點擊網站的高級設置在「已啓用的協議」中添加net.tcp

 

右擊網站,編輯協議-添加,選擇net.tcp,綁定信息輸入4507:*,肯定

點擊瀏覽網站,會列出以下信息

選擇MessageService.svc連接,也可直接在瀏覽器上輸入http://localhost:8081/MessageService.svc

瀏覽器會顯示以下:

已建立服務。

若要測試此服務,須要建立一個客戶端,並將其用於調用該服務。可使用下列語法,從命令行中使用 svcutil.exe 工具來進行此操做:



svcutil.exe net.tcp://barry:4507/MessageService.svc/mex

 

爲了讓WCF可以跨域,須要在IIS的默認網站根目錄下添加clientaccesspolicy.xml,有必要時還添加crossdomain.xml

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>

 

crossdomain.xml

<?xml version="1.0" ?>

<cross-domain-policy>

  <allow-access-from domain="*" />

</cross-domain-policy>

 

IIS默認網站是Default Web Site根目錄是此網站的根目錄,地方要找正確

 

  1. 回到項目中,在解決方案中,添加一個名爲SilverlightApp的silverlight程序,

點擊引用,添加服務器引用,輸入net.tcp://localhost:4507/MessageService.svc/mex

在高級中,在字典信息類型中取消 從新使用引用的程序集中的類型

 

肯定添加

 

MainPage界面設計:

<UserControl x:Class="SilverlightApp.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">

 

    <Grid x:Name="LayoutRoot" Background="White">

        <StackPanel Orientation="Vertical">

            <Button x:Name="btnCreateUser1" Content="生成用戶1" Width="100" Margin="0,10,0,0" Click="btnCreateUser1_Click" />

            <Button x:Name="btnCreateUser2" Content="生成用戶2" Width="100" Margin="0,10,0,0" Click="btnCreateUser2_Click"/>

            <TextBox x:Name="tbContent" Width="200" Height="150" Margin="0,10,0,0"/>

            <Button x:Name="btnSend" Content="發送" Width="100" Margin="0,10,0,0" Click="btnSend_Click"/>

            <TextBox x:Name="tbContentRecord" Width="200" Height="150" Margin="0,10,0,0"/>

        </StackPanel>

    </Grid>

</UserControl>

 

後臺代碼:

public partial class MainPage : UserControl

    {

      

        MessageInfo message = new MessageInfo();

        public MainPage()

        {

            InitializeComponent();

          

        }

 

        private void btnSend_Click(object sender, RoutedEventArgs e)

        {

            MessageManageClient client = new MessageManageClient();

            message.Content = tbContent.Text;

            message.SendTime = DateTime.Now;

            client.SendMessageAsync(message);

            client.SendMessageCompleted += (ds, de) =>

            {

                if (de.Result)

                {

                    MessageBox.Show("發送成功!");

                }

                else

                {

                    MessageBox.Show("發送失敗!");

                }

            };

        }

 

        private void btnCreateUser1_Click(object sender, RoutedEventArgs e)

        {

            MessageManageClient client = new MessageManageClient();

            UserInfo formUser = new UserInfo()

            {

                Id = 123,

                Name = "張三"

            };

            UserInfo toUser = new UserInfo()

            {

                Id = 234,

                Name = "李四",

            };

 

            message.FromUser = formUser;

            message.ToUser = toUser;

            message.Content = tbContent.Text;

            message.SendTime = DateTime.Now;

            client.RequestMessageAsync(formUser);

            client.RequestMessageCompleted += (rs, re) =>

            {

                if (re.Result)

                {

                    MessageBox.Show("用戶"+formUser.Id+"建立成功!");

                }

            };

            client.GetMessageReceived += (gs, ge) =>

            {

                if (ge.Error == null)

                {

                    tbContentRecord.Text += "\r" + "來自:" + ge.message.FromUser.Name + ",內容:" + ge.message.Content + ",時間:" + ge.message.SendTime.ToShortTimeString();

                }

            };

        }

 

        private void btnCreateUser2_Click(object sender, RoutedEventArgs e)

        {

            MessageManageClient client = new MessageManageClient();

            UserInfo formUser = new UserInfo()

            {

                Id = 234,

                Name = "李四"

            };

            UserInfo toUser = new UserInfo()

            {

                Id = 123,

                Name = "張三",

            };

 

            message.FromUser = formUser;

            message.ToUser = toUser;

            message.Content = tbContent.Text;

            message.SendTime = DateTime.Now;

            client.RequestMessageAsync(formUser);

            client.RequestMessageCompleted += (rs, re) =>

            {

                if (re.Result)

                {

                    MessageBox.Show("用戶" + formUser.Id + "建立成功!");

                }

            };

            client.GetMessageReceived += (gs, ge) =>

            {

                if (ge.Error == null)

                {

                    tbContentRecord.Text += "\r" + "來自:" + ge.message.FromUser.Name + ",內容:" + ge.message.Content + ",時間:" + ge.message.SendTime.ToShortTimeString();

                }

            };

        }

}

 

  1. 將WcfService項目設爲啓動項目,將SilverlightAppTestPage.html設爲啓動頁面,

 

F5運行程序,複製頁面路徑,同時打開兩個相同的頁面

兩個頁面分別點生成用戶一、生成用戶2,

 

成功後,就可相互發送信息了

 

後記。對於net.tcp雙工有時候真心讓人不知道問題在那兒,什麼跨域XML。配置文件這些都沒問題,有時候就是仍是要報什麼跨域錯誤,有時候又不報跨域錯誤,真讓人摸不着頭腦,若是有對此瞭解深入的,請大神指點。

源碼地址:

http://download.csdn.net/detail/cyb331/5657061源碼不當心加上分了,須要的留下郵箱

相關文章
相關標籤/搜索