写点什么

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

作者:南蓬幽
  • 2022 年 8 月 10 日
    河南
  • 本文字数:4319 字

    阅读完需:约 14 分钟

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

WCF 和 TCP 消息通信练习

客户端

MainWindow.xaml

主页面

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


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("用户1", 0, 0); StartWindow("用户2", 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

聊天界面

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


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+"说: "+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("与服务端连接失败:" + ex.Message); return; } }
private void launch_Click(object sender, RoutedEventArgs e) { client.Talk(UserName, messagebox.Text); messagebox.Text = ""; }

private void messagebox_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { client.Talk(UserName, messagebox.Text); messagebox.Text = ""; } } }}
复制代码

服务端

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 = "IService", 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 = ""; for (int i = 0; i < CC.Users.Count; i++) { str += CC.Users[i].UserName + "、"; } 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); } } }}
复制代码

实验结果


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

发布于: 刚刚阅读数: 3
用户头像

南蓬幽

关注

还未添加个人签名 2022.07.27 加入

学习学习

评论

发布
暂无评论
【C#】WCF和TCP消息通信练习,实现群聊功能_签约计划第三季_南蓬幽_InfoQ写作社区