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


    WCF和TCP消息通信练习

    客户端

    MainWindow.xaml

    主页面
    在这里插入图片描述

    <Window x:Class="Lab_5.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Lab_5"
            mc:Ignorable="d"
            Title="主界面" Height="450" Width="800">
        <Grid>
            <Button Name="bt1" Content="同时启动两个客户端(测试用)" HorizontalAlignment="Left" Margin="259,150,0,0" VerticalAlignment="Top" Width="265" Height="27" Click="bt1_Click"/>
            <Button Name="bt2" Content="只启动一个客户端(实际情况)" HorizontalAlignment="Left" Margin="259,252,0,0" VerticalAlignment="Top" Width="265" Height="28" Click="bt2_Click"/>
        </Grid>
    </Window>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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
    {
        /// 
        /// MainWindow.xaml 的交互逻辑
        /// 
        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();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    ChatCline.xaml

    聊天界面
    在这里插入图片描述

    <Window x:Class="Lab_5.ChatCline"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Lab_5"
            mc:Ignorable="d"
            Title="群聊客户端" Height="450" Width="800">
        <Grid>
            <TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="用户名:" VerticalAlignment="Top" Height="28" Width="69" FontSize="14"/>
            <TextBox Name="textbox" HorizontalAlignment="Left" Height="28" Margin="84,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="217" FontSize="14"/>
            <Button Name="login" Content="登录" HorizontalAlignment="Left" Margin="333,10,0,0" VerticalAlignment="Top" Width="75" Height="28" FontSize="14" Click="login_Click"/>
            <Canvas Name="box" HorizontalAlignment="Left" Height="363" Margin="0,57,-0.4,0" VerticalAlignment="Top" Width="794">
                <TextBlock Canvas.Left="10" TextWrapping="Wrap" Text="在线用户" Canvas.Top="10" Height="24" Width="74" FontSize="14"/>
                <ListBox Name="listbox" Height="324" Canvas.Top="39" Width="84" FontSize="14"/>
                <TextBlock Canvas.Left="127" TextWrapping="Wrap" Text="对话信息" Canvas.Top="10" Height="24" Width="657" TextAlignment="Center" FontSize="14"/>
                <ListBox Name="listmessage" Height="252" Canvas.Left="104" Canvas.Top="39" Width="680" FontSize="14"/>
                <TextBlock Canvas.Left="104" TextWrapping="Wrap" Text="发言:" Canvas.Top="314" Height="27" Width="50" FontSize="14"/>
                <TextBox Name="messagebox" Height="27" Canvas.Left="154" TextWrapping="Wrap" Text="" Canvas.Top="314" Width="481" FontSize="14" KeyDown="messagebox_KeyDown"/>
                <Button Name="launch" Content="发送" Canvas.Left="679" Canvas.Top="314" Width="75" Height="27" FontSize="14" Click="launch_Click"/>
            </Canvas>
    
        </Grid>
    </Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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
    {
        /// 
        /// ChatCline.xaml 的交互逻辑
        /// 
        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 = "";
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    服务端

    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;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    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);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    实验结果

    在这里插入图片描述

  • 相关阅读:
    Snipaste 截图悬浮工具【实用教程】
    交换机与路由器技术-34-动态NAT
    考过PMP之后,要不要继续学CSPM?
    Java学习笔记4.4.2 包装类 - 基本数据类型、包装类与字符串相互转换
    环境主题静态HTML网页作业作品 大学生环保网页设计制作成品 简单DIV CSS布局网站
    结构型设计模式之代理模式
    定时执行专家 - 循环触发的危险操作,例如:电脑循环关机、循环重启、循环注销等,请谨慎尝试
    1.1 OpenCV是什么
    记一次 .NET 差旅管理后台 CPU 爆高分析
    PD仿真算法中变形梯度矩阵的极分解
  • 原文地址:https://blog.csdn.net/qq_46556714/article/details/126030847