InChatter系统之服务客户端的开发

今天终于开始客户端的开发了,客户端完成以后,我们将可以进行简单的交流。开发完成的程序只是一个很简单的雏形,在本系统完成以后,以及完成的过程中,大家都可以下载源码,在此基础上融入自己的想法和尝试,可以按照自己的思路,完成后面的部分。

下面我们开始客户端的开发,我们新建一个类库项目,作为与服务器端交互的中枢,同时也是为了分离服务和界面逻辑。目前我们将首先我们WPF客户端开发,在稍后的时间,我们再进行Winform的开发。

1.新建类库项目,作为客户端与服务器端的交互中枢

2.在新项目上添加服务引用

3.在弹出的窗体中输入我们的服务地址(服务地址可以从服务器端获取到):net.tcp://localhost:1121/InChatter

发生错误:元数据包含无法解析的引用:“net.tcp://localhost:1121/InChatter"

为什么会这样,其实这个跟我们的服务器端有关,我们设置了绑定的地址,但是并没有设置元数据的地址,记得在上节我说过,我们的配置文件配置的tcp连接方式,是有问题的,其实就是这个。

解决这个问题的方法有两种:

(1)为服务添加元数据的地址,我们在NetTcpBinding的基础上修改,这个应该说是比较正统的方法,当然不是说另外一种方法不正确了,看个人习惯了。

首先修改我们的服务器端代码,注意行号4以及行号4,我们添加了新的Behaviour,第10行提供了元数据的获取路径和方式

 1             using (ServiceHost host = new ServiceHost(typeof(Chat)))
 2             {
 3                 NetTcpBinding binding = new NetTcpBinding();
 4                 Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
 5                 binding.Security.Mode = SecurityMode.None;
 6                 //会话保持时间
 7                 binding.ReceiveTimeout = TimeSpan.FromHours(2);
 8                 host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = false });
 9                 host.AddServiceEndpoint(typeof(IChat), binding, "net.tcp://localhost:1121/InChatter");
10                 host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "net.tcp://localhost:1121/InChatter/Mex");
11                 host.Opened += host_Opened;
12                 try
13                 {
14                     host.Open();
15 
16                 }
17                 catch (Exception ex)
18                 {
19                     Console.WriteLine(ex.Message);
20                 }
21                 Console.WriteLine("Press 'exit' to exit!");
22                 string enterStr = Console.ReadLine();
23                 while (enterStr.ToLower() != "exit")
24                 {
25                     enterStr = Console.ReadLine();
26                 }
27             }

代码方面有个问题就是第8行一定要在AddServiceEndPoint前面,否则会出下面的问题:

未处理InvalidOperationException:在服务InChatter.Service.Chat实现的协定列表中找不到协定名称“IMetadataExchange”。将ServiceMetadataBehaviour添加到配置文件或直接添加到ServiceHost,以启用对该协定的支持。

xml的配置方式如下:

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="ChatServiceBinding" transactionFlow="true"/>
      </netTcpBinding>
    </bindings>
    <services>
      <service name="InChatter.Service.Chat" behaviorConfiguration="ChatBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:1121/InChatter" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="ChatServiceBinding"  contract="InChatter.Service.IChat" />
        <endpoint address="Mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ChatBehavior">
          <serviceMetadata httpGetEnabled="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

(2)第二种方法就是使用http来定义我们元数据访问路径,其实也是前一节我们所采用的方式

 1            Uri baseUri = new Uri("http://localhost:1378/InChatter");
 2             using (ServiceHost host = new ServiceHost(typeof(Chat), baseUri))
 3             {
 4                 NetTcpBinding binding = new NetTcpBinding();
 5                 binding.Security.Mode = SecurityMode.None;
 6                 //会话保持时间
 7                 binding.ReceiveTimeout = TimeSpan.FromHours(2);
 8                 host.AddServiceEndpoint(typeof(IChat), binding, "net.tcp://localhost:1121/InChatter");
 9                 host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
10                 host.Opened += host_Opened;
11                 try
12                 {
13                     host.Open();
14 
15                 }
16                 catch (Exception ex)
17                 {
18                     Console.WriteLine(ex.Message);
19                 }
20                 Console.WriteLine("Press 'exit' to exit!");
21                 string enterStr = Console.ReadLine();
22                 while (enterStr.ToLower() != "exit")
23                 {
24                     enterStr = Console.ReadLine();
25                 }
26             }

这里要注意,第1行以及第9行,而我们在添加服务引用的时候,自然需要使用http://localhost:1378/InChatter这个路径

4.确定服务的命名空间,就完成了服务的添加

我们明明的ChatServer,在生成以后,会在我们命名空间的基础上追加,如图所示。

源码提供给大家:下载源码到CodePlex下载最新版本

posted @ 2013-11-09 22:48  Skysper  阅读(1505)  评论(2编辑  收藏  举报