当前位置:网站首页>【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);
}
}
}
}
实验结果
边栏推荐
- flex&bison系列第一章:flex Hello World
- 365天挑战LeetCode1000题——Day 053 求解方程 解析 模拟
- 3D游戏建模学习路线
- 剑指 Offer II 042. 最近请求次数-队列法
- Today's bug, click on the bug that the Windows dynamic wallpaper disappears in the win10 taskbar, and no solution has been found yet.
- MySQL 原理与优化:Update 优化
- set和map使用讲解
- 服务器上行带宽和下行带宽指的是什么
- FPGA工程师面试试题集锦81~90
- Three schemes of SQL query across the table
猜你喜欢
NPDP|传统行业产品经理如何进行能力提升?
We used 48h to co-create a web game: Dice Crush, to participate in international competitions
IoU、GIoU、DIoU、CIoU四种损失函数总结
【OpenCV】-物体的凸包
搭建自己的以图搜图系统 (一):10 行代码搞定以图搜图
Optimizing Bloom Filter: Challenges, Solutions, and Comparisons论文总结
从企业的视角来看,数据中台到底意味着什么?
位算符详解 按位与、或、异或、取反、左移、右移
「POJ 3666」Making the Grade 题解(两种做法)
QoS服务质量七交换机拥塞管理
随机推荐
【自然语言处理】【向量表示】PairSupCon:用于句子表示的成对监督对比学习
【深度学习前沿应用】图像风格迁移
剑指 Offer II 034. 外星语言是否排序-辅助数组法
stm32中的CAN通讯列表模式配置解析与源码
redis.exceptions.DataError: Invalid input of type: ‘dict‘. Convert to a byte, string or number first
LeetCode·26.删除有序数组中的重复项·双指针
mysql 中大小写问题
杭电多校七 1003-Counting Stickmen(组合数学)
入门:人脸专集2 | 人脸关键点检测汇总(文末有相关文章链接)
Unity_Stack<T>()的应用(多个次级界面后的返回逻辑)
第15章_锁
openssl查看证书信息
阿里云贾朝辉:云 XR 平台支持彼真科技呈现国风科幻虚拟演唱会
dumpsys meminfo 详解
Redis command---key chapter (super complete)
GBASE 8s 高可用RSS集群搭建
友邦人寿可观测体系设计与落地
The servlet mapping path matching resolution
JVM基本结构
Introduction to 3 d games beginners essential 】 【 modeling knowledge