当前位置:网站首页>【C#】WCF和TCP消息通信练习,实现群聊功能

【C#】WCF和TCP消息通信练习,实现群聊功能

2022-08-10 18:53:00 InfoQ

WCF和TCP消息通信练习

客户端

MainWindow.xaml

主页面
有两个按钮,一个是只启动一个客户端,另一个是启动两个客户端模拟两个人聊天

null

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Lab_5
{
 /// <summary>
 /// MainWindow.xaml 的交互逻辑
 /// </summary>
 public partial class MainWindow : Window
 {
 public MainWindow()
 {
 InitializeComponent();
 }

 private void StartWindow(string userName, int left, int top)
 {
 ChatCline w = new ChatCline();
 w.Left = left;
 w.Top = top;
 w.UserName = userName;
 w.Owner = this;
 w.Closed += (sender, e) => this.Activate();//关闭子窗体时激活父窗体
 w.Show();
 }

 private void bt1_Click(object sender, RoutedEventArgs e)
 {
 StartWindow(&quot;用户1&quot;, 0, 0);
 StartWindow(&quot;用户2&quot;, 400, 300);
 }

 private void bt2_Click(object sender, RoutedEventArgs e)
 {
 ChatCline w = new ChatCline();
 w.Owner = this;
 w.Closed += (sendObj, args) => this.Activate();
 w.Show();
 }
 }
}

ChatCline.xaml

聊天界面
主要包括登录,显示用户名,发送信息,显示在线用户等功能相当于一个聊天室。

null

ChatCline.xaml.cs

using Lab_5.ServiceReference1;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Lab_5
{
 /// <summary>
 /// ChatCline.xaml 的交互逻辑
 /// </summary>
 public partial class ChatCline : Window,IService1Callback
 {
 public ChatCline()
 {
 InitializeComponent();
 this.Closing += ChatCline_Closing;
 box.Visibility = System.Windows.Visibility.Hidden;
 }

 private Service1Client client;

 public string UserName
 {
 get { return textbox.Text; }
 set { textbox.Text = value; }
 }

 private void ChatCline_Closing(object sender, CancelEventArgs e)
 {
 if (client != null)
 {
 client.Logout(UserName); 
 client.Close();
 }
 }

 private void AddMessage(string str)
 {
 TextBlock t = new TextBlock();
 t.Text = str;
 listmessage.Items.Add(t);
 }

 public void InitUsersInfo(string UsersInfo)
 {
 if (UsersInfo.Length == 0) return;
 string[] users = UsersInfo.Split('、');
 for (int i = 0; i < users.Length; i++)
 {
 listbox.Items.Add(users[i]);
 }
 }

 public void ShowLogin(string loginUserName)
 {
 if (loginUserName == UserName)
 {
 box.Visibility = System.Windows.Visibility.Visible;
 }
 listbox.Items.Add(loginUserName);
 }

 public void ShowLogout(string userName)
 {
 listbox.Items.Remove(userName);
 }

 public void ShowTalk(string userName, string message)
 {
 AddMessage(userName+&quot;说: &quot;+message);
 }

 private void login_Click(object sender, RoutedEventArgs e)
 {
 UserName = textbox.Text;
 InstanceContext context = new InstanceContext(this);
 client = new Service1Client(context);
 try
 {
 client.Login(textbox.Text);
 login.IsEnabled = false;
 }
 catch (Exception ex)
 {
 MessageBox.Show(&quot;与服务端连接失败:&quot; + ex.Message);
 return;
 }
 }

 private void launch_Click(object sender, RoutedEventArgs e)
 {
 client.Talk(UserName, messagebox.Text);
 messagebox.Text = &quot;&quot;;
 }


 private void messagebox_KeyDown(object sender, KeyEventArgs e)
 {
 if (e.Key == Key.Enter)
 {
 client.Talk(UserName, messagebox.Text);
 messagebox.Text = &quot;&quot;;
 }
 }
 }
}

服务端

Users.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WcfServiceLibrary1
{
 class Users
 {
 public string UserName { get; set; }
 public readonly IService1Callback callback;

 public Users(string userName, IService1Callback callback)
 {
 this.UserName = userName;
 this.callback = callback;
 }
 }
}

CC.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WcfServiceLibrary1
{
 class CC
 {
 public static List<Users> Users { get; set; }

 static CC()
 {
 Users = new List<Users>();
 }

 public static Users GetUser(string userName)
 {
 Users user = null;
 foreach (var v in Users)
 {
 if (v.UserName == userName)
 {
 user = v;
 break;
 }
 }
 return user;
 }
 }
}

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary1
{
 [ServiceContract(Namespace = &quot;IService&quot;,
 CallbackContract = typeof(IService1Callback))]
 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
 public interface IService1
 {

 // TODO: 在此添加您的服务操作
 [OperationContract(IsOneWay = true)]
 void Login(string userName);

 [OperationContract(IsOneWay = true)]
 void Logout(string userName);

 [OperationContract(IsOneWay = true)]
 void Talk(string userName, string message);
 }


 public interface IService1Callback
 {
 [OperationContract(IsOneWay = true)]
 void ShowLogin(string loginUserName);

 [OperationContract(IsOneWay = true)]
 void ShowLogout(string userName);

 [OperationContract(IsOneWay = true)]
 void ShowTalk(string userName, string message);

 [OperationContract(IsOneWay = true)]
 void InitUsersInfo(string UsersInfo);
 }

}

Service1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary1
{
 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
 public class Service1 : IService1
 {
 public void Login(string userName)
 {
 OperationContext context = OperationContext.Current;
 IService1Callback callback = context.GetCallbackChannel<IService1Callback>();
 Users newUser = new Users(userName, callback);
 string str = &quot;&quot;;
 for (int i = 0; i < CC.Users.Count; i++)
 {
 str += CC.Users[i].UserName + &quot;、&quot;;
 }
 newUser.callback.InitUsersInfo(str.TrimEnd('、'));
 CC.Users.Add(newUser);
 foreach (var user in CC.Users)
 {
 user.callback.ShowLogin(userName);
 }
 }

 public void Logout(string userName)
 {
 Users logoutUser = CC.GetUser(userName);
 CC.Users.Remove(logoutUser);
 logoutUser = null;
 foreach (var user in CC.Users)
 {
 user.callback.ShowLogout(userName);
 }
 }

 public void Talk(string userName, string message)
 {
 Users user = CC.GetUser(userName);
 foreach (var v in CC.Users)
 {
 v.callback.ShowTalk(userName, message);
 }
 }
 }
}

实验结果

null
通过本次练习简单掌握和理解了WCF和TCP消息通信,实现聊天功能。
原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/797e655f522ea8225992c75bd