zoukankan      html  css  js  c++  java
  • 使用Silverlight4与Wcf4的Net.tcp实现的简单聊天室

    这两天研究net.tcp与Silverlight4进行通信都快疯了,不过还好,苍天不负苦心人啊,这俩天总算是调通了。

    先简单说一下,为了更好地实现双向通信,.NET Framework在 3.0的时候引入了一个全新的通信协议Net.TCP并作为WCF的一部分。现在Net.TCP将包含在Silverlight 4中,相比于HTTP Polling Duplex,它极大地改进了吞吐量和连接的数量。
    我们可以通过Silverlight 4绑定到HTTP Duplex Services上,因而应用可以不断轮询服务以进行更新,这模拟了双向通讯的工作方式。Silverlight 4则引入了一个更好的解决方案:Net.TCP Port Sharing Service。与HTTP不同,Net.TCP提供了本地的双向通信机制,极大地改进了应用的性能。打开的端口可以由多个应用共享,然而Silverlight只能访问介于4502-4534范围之间的端口。
    根据微软WCF开发经理Tomasz Janczuk所述,相对于HTTP Duplex来说,Net.TCP在如下方面进行了重大的改进:
        * 吞吐量:对于UI线程来说提升了5.5倍,对于worker线程来说提升了870倍。
        * 最大的客户端数量:服务器可支持的连接客户端数量是之前的5-6倍。
    该协议适用于对通信速度要求很高的Silverlight应用。但其一个严重缺陷是所使用的一系列端口通常会被防火墙阻止,因此它不适合于公网、外部应用,而适合于局域网。另一个问题是它不支持SSL,这样就会遇到安全问题,Janczuk说将在未来解决该问题。

    特分享一下这个demo,希望对大家有帮助。

    项目结构如下图所示:  WebChat.Service 是一个宿主程序,主要是用来向Silverlight提供服务和监听943与4502-4534这个范围的自定端口的。

    我们启动WebChat.Service宿主程序,进行监听商品,在命令提示符下打入netstat -na来查看我们监听的端口。

    我监听的是943和4503这两个端口。

    Silverlight使用net.tcp访问的时候要求请一个有策略文件,可以在程序里面这写也可以放到项目的根目录下。clientaccesspolicy.xml这个是必须的

    如果您使用的是vs2010的话,可以在“在线模版”里面找到Silverlight TCP Socket Policy这个模版,新建就可以得到监听943端口的程序。哈哈!

    里面有两个cs文件,

    SocketPolicy.cs

    SocketPolicy.cs

    1 public static class SocketPolicy
    2 {
    3 public const string Policy = @"
    4 <?xml version=""1.0"" encoding =""utf-8""?>
    5 <access-policy>
    6 <cross-domain-access>
    7 <policy>
    8 <allow-from>
    9 <domain uri=""*"" />
    10 </allow-from>
    11 <grant-to>
    12 <socket-resource port=""4502-4530"" protocol=""tcp"" />
    13 </grant-to>
    14 </policy>
    15 </cross-domain-access>
    16 </access-policy>
    17 ";
    18 }

    还有一个文件,内容太长,这里就不给代码了,大家可以自己新建一下看看。

    拷到你的项目中就可以,不用手写。

    由于代码很多这里我就不全写出来了,只把需要注意的地方告诉大家,我会把整个的demo提供给大家下载。

    App.config 做为这个宿主程序的灵魂,这个破config整得我都快疯掉了。这里面就是普通的wcf配置,请注意一下我写注释的地方就可以。

    代码

    1 <?xml version="1.0" encoding="utf-8" ?>
    2  <configuration>
    3 <system.web>
    4 <compilation debug="true" />
    5 </system.web>
    6 <system.serviceModel>
    7 <protocolMapping>
    8 <add scheme="tcp" binding="netTcpBinding"/>
    9 </protocolMapping>
    10
    11 <bindings>
    12 <customBinding> <!--注意,这里只能使用自定义的绑定,应为Silverlight4测试版并不完全技术net.tcp-->
    13 <binding name="WebChat.Service.ChatService1">
    14 <binaryMessageEncoding></binaryMessageEncoding>
    15 <tcpTransport></tcpTransport>
    16 </binding>
    17 </customBinding>
    18 <netTcpBinding>
    19 <binding name ="myTcpBinding" portSharingEnabled="true"></binding>
    20 </netTcpBinding>
    21 </bindings>
    22
    23 <services>
    24 <service behaviorConfiguration="WebChat.Service.ChatServiceBehavior" name="WebChat.Service.ChatService">
    25 <endpoint
    26 address="Service" binding="customBinding"
    27 contract="WebChat.Service.IChatService"
    28 bindingConfiguration="WebChat.Service.ChatService1" >
    29 </endpoint>
    30 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> <!--这个一个要写的!!!暴露元数据。-->
    31 <host>
    32 <baseAddresses>
    33 <add baseAddress="http://localhost:4504/"/>
    34 <add baseAddress="net.tcp://localhost:4503/"/>
    35 </baseAddresses>
    36 </host>
    37 </service>
    38 </services>
    39 <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    40 <behaviors>
    41 <serviceBehaviors>
    42 <behavior name="WebChat.Service.ChatServiceBehavior">
    43 <serviceMetadata httpGetEnabled="true" />
    44 <serviceDebug includeExceptionDetailInFaults="false" />
    45 </behavior>
    46 </serviceBehaviors>
    47 </behaviors>
    48 </system.serviceModel>
    49  </configuration>

    宿主程序启动

    代码

    1 class Program
    2 {
    3 static void Main(string[] args)
    4 {
    5 PolicyServer ps = new PolicyServer(SocketPolicy.Policy); //启动943策略文件监听端口
    6
    7 ServiceHost host = new ServiceHost(typeof(WebChat.Service.ChatService));
    8 Console.WriteLine();
    9 host.Open();
    10 System.Console.WriteLine("聊天室服务器开始监听...");
    11 System.Console.WriteLine("按 ENTER 停止服务器监听...");
    12 System.Console.ReadLine();
    13 host.Abort();
    14 host.Close();
    15 ps.Close();
    16 }
    17 }

    客户端添加服务的时候没有什么太需要注意的地方。写入你本机的ip或127.0.0.1或localhost加上你监听的端口号再加上mex(请求元数据)就OK了。

    在添加引用和调用的时候宿主程序一定要运行,应为SL访问的时候是通过你监听的端口进数据通信的。

    客户端

    1 private void btnClick_Click(object sender, RoutedEventArgs e)
    2 {
    3
    4 ServiceReference1.ChatServiceClient sc;
    5 EndpointAddress ea = new EndpointAddress("net.tcp://localhost:4503/Service");
    6 BindingElement metaElement = new TcpTransportBindingElement();
    7 CustomBinding metaBind = new CustomBinding(metaElement);
    8
    9
    10 sc = new ServiceReference1.ChatServiceClient(metaBind, ea);
    11 sc.JoinAsync("测试用户名");
    12 sc.JoinCompleted += (se, args) =>
    13 {
    14 MessageBox.Show(args.Result[0]);
    15 };
    16 }

    EndpointAddress ea = new EndpointAddress("net.tcp://localhost:4503/Service");

    需要注意的是net.tcp://localhost:4503/Service这个终结点的地址是你ip+监听的端口+宿主程序app.config中定义的终结点地址

                    <endpoint
                       address="Service"  binding="customBinding"
                       contract="WebChat.Service.IChatService"
                      bindingConfiguration="WebChat.Service.ChatService1" >
                    </endpoint>

    下载地址:http://download.csdn.net/source/1910480

    没有整理过代码,大家将就着看吧!

    REF:http://www.cnblogs.com/homezzm/archive/2009/12/17/1626264.html
  • 相关阅读:
    沉淀再出发:在python3中导入自定义的包
    沉淀再出发:java中的equals()辨析
    沉淀再出发:web服务器和应用服务器之间的区别和联系
    沉淀再出发:jetty的架构和本质
    沉淀再出发:dubbo的基本原理和应用实例
    沉淀再出发:OpenStack初探
    沉淀再出发:Spring的架构理解
    沉淀再出发:关于IntelliJ IDEA使用的一些总结
    沉淀再出发:spring boot的理解
    沉淀再出发:Bean,JavaBean,POJO,VO,PO,EJB等名词的异同
  • 原文地址:https://www.cnblogs.com/dotfun/p/1640111.html
Copyright © 2011-2022 走看看