当前位置:网站首页>【C#】WCF和TCP消息通信练习,实现群聊功能
【C#】WCF和TCP消息通信练习,实现群聊功能
2022-08-10 18:53:00 【InfoQ】
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);
}
}
}
}
实验结果

边栏推荐
- 剑指 Offer 27. 二叉树的镜像(翻转二叉树)
- QoS Quality of Service Seven Switch Congestion Management
- 多种深度模型实现手写字母MNIST的识别(CNN,RNN,DNN,逻辑回归,CRNN,LSTM/Bi-LSTM,GRU/Bi-GRU)
- LeetCode·283.移除零·双指针
- 人生苦短,开始用go
- The Biotin-PEG3-Br/acid/NHS ester/alcohol/amine collection that everyone wants to share
- 西安Biotin-PEG8-IA_IA-PEG8-生物素供应商
- 【初学必备】3d游戏建模入门基础知识
- 谈谈宝石方块游戏中的设计
- ARouter使用自定义注解处理器,自动生成跳转Activity的代码,避免手动填写和管理path
猜你喜欢
2022-08-09 Study Notes day32-IO Stream
多种深度模型实现手写字母MNIST的识别(CNN,RNN,DNN,逻辑回归,CRNN,LSTM/Bi-LSTM,GRU/Bi-GRU)
友邦人寿可观测体系设计与落地
我们用48h,合作创造了一款Web游戏:Dice Crush,参加国际赛事
MySQL 原理与优化:Update 优化
[Image segmentation] Image segmentation based on cellular automata with matlab code
2022-08-09 学习笔记 day32-IO流
API 网关的功能
【Knowledge Sharing】What is SEI in the field of audio and video development?
Keil5退出仿真调试卡死的解决办法
随机推荐
Intelligent bid strategy how to affect advertising effectiveness?
Consul Introduction and Installation
含有PEG 间隔基和一个末端伯胺基团(CAS:1006592-62-6)化学试剂
【自然语言处理】【向量表示】PairSupCon:用于句子表示的成对监督对比学习
C#/VB.NET 将PDF转为PDF/X-1a:2001
弘玑Cyclone与风变科技达成战略合作:优势互补聚焦数字化人才培养
Win11如何清除最近打开过的文件记录?
pyspark columns merge into one row
网络拓扑管理
About npm/cnpm/npx/pnpm and yarn
TikTok选品有什么技巧?
入门:人脸专集2 | 人脸关键点检测汇总(文末有相关文章链接)
搭建自己的以图搜图系统 (一):10 行代码搞定以图搜图
状态压缩dp蒙德里安的梦想
服务器上行带宽和下行带宽指的是什么
西安凯新(CAS:2408831-65-0)Biotin-PEG4-Acrylamide 特性
阿里云贾朝辉:云 XR 平台支持彼真科技呈现国风科幻虚拟演唱会
剑指 Offer 27. 二叉树的镜像(翻转二叉树)
L2-035 完全二叉树的层序遍历
什么是企业知识库?有什么作用?如何搭建?