WCF双工通信聊天室(WPF+C#)

目录

WCF部分

Service1.svc.cs源码

IService1.cs源码

WPF部分

MainWindow.xaml.cs源码

MainWindow.xaml源码

操作


有更好的想法可以交流


WCF部分

要用双工通信先配置文件在Web.config那里,怎么配置自行搜索。

关于WCF和WPF的服务引用可以看这篇文章WPF调WCF服务端

Service1.svc.cs源码

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

namespace WcfService_ChatService
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
    // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
    public class Service1 : IService1
    {
        public Service1()
        {
            if (Users.userList == null)
                Users.userList = new List<User>();
        }
        private IChatServiceCallback callback;
        
        public void Login(string username)
        {
            OperationContext context = OperationContext.Current;
            callback = context.GetCallbackChannel<IChatServiceCallback>();
            User newUser = new User(username, callback);
            newUser.userName = username;
            foreach (var userone in Users.userList)
            {
                
                if(newUser.userName == userone.userName)
                {
                    callback.ShowWrongLogin(userone.userName);
                    return;
                }
            }
           
            Users.userList.Add(newUser);
            
            foreach (var usertwo in Users.userList)
            {
                usertwo.callback.ShowLogin(username, Users.userList.Count);
                //usertwo.callback.ShowUserList(Users.userList);
                
            }
        }

        public void Logout(string userName)
        {
            
            User removeUser = null;
            foreach (User one in Users.userList)
            {
                if (one.userName == userName)
                {
                    removeUser = one;
                    
                    break;
                }
            }
            if(removeUser == null)
            {
                callback.ShowWrongLogout(userName);
                return;
            }
           
            Users.userList.Remove(removeUser);
            foreach (var user in Users.userList)
            {   
                user.callback.ShowLogout(userName, Users.userList.Count);
                user.callback.ShowUserList(Users.userList);
            }
        }

        public void sendInfo(string info , string userName)
        {
            foreach (var user in Users.userList)
            {
                    user.callback.ShowSendInfo(info, userName);
            }               
        }
        public void PrivateChat(string userName, string SelectName, string T)
        {
            foreach(User user in Users.userList)
            {
                if(user.userName == SelectName)
                {
                    user.callback.ShowPrivateChat(userName,T);
                }
            }
        }

        public void LoginList()
        {
            foreach (User user in Users.userList)
            {
                user.callback.ShowUserList(Users.userList);
            }
           
        }
        public class Users
        {
            public static List<User> userList;
        }

    }
}

IService1.cs源码

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

using static WcfService_ChatService.Service1;

namespace WcfService_ChatService
{
    [ServiceContract(CallbackContract = typeof(IChatServiceCallback))]
    //服务端
    public interface IService1
    {
        [OperationContract(IsOneWay = true)]
        void Login(string userName);

        [OperationContract(IsOneWay = true)]
        void sendInfo(string info,string userName);

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

        [OperationContract(IsOneWay = true)]
        void LoginList();

        [OperationContract(IsOneWay = true)]
        void PrivateChat(string userName , string SelectName , string Text);
    }
    [DataContract]
    public class users
    {
        [DataMember] public String userName { get; set; }
    }
    [DataContract]
    public class User
    {
        /// <summary>登录的用户名</summary>
        [DataMember] public string userName;
        public DateTime loginTime;
        public readonly IChatServiceCallback callback;
        public User(string userName, IChatServiceCallback callback)
        {
            //this.userName = userName;
            this.callback = callback;
        }
    }
        //客户端
        public interface IChatServiceCallback
    {
        [OperationContract(IsOneWay = true)]
        void ShowLogin(string userName, int userCount);

        [OperationContract(IsOneWay = true)]
        void ShowSendInfo(string info , string infousername);

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

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

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

        [OperationContract(IsOneWay = true)]
        void ShowUserList(List<User> users);

        [OperationContract(IsOneWay = true)]
        void ShowPrivateChat(string userName , string text);


    }
}

WPF部分

MainWindow.xaml.cs源码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
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.Navigation;
using System.Windows.Shapes;
using WpfApp_ChatClient.ServiceReference1;

namespace WpfApp_ChatClient
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window, IService1Callback
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Closing += Window_Closing;
            this.btnLogout.IsEnabled = false;
            this.btnSend.IsEnabled = false;
        }
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            client.Logout(UserName);
            e.Cancel = false;
        }

        public string UserName;
        private Service1Client client;

        //登录
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            UserName = textBoxUserName.Text;
            if (textBoxUserName.Text == String.Empty)
            {
                MessageBox.Show("用户名不能为空!!!");
                return;
            }
            InstanceContext context = new InstanceContext(this);
            client = new Service1Client(context);

            client.Login(textBoxUserName.Text);
            serviceTextBlock.Text = "服务端地址:" + client.Endpoint.ListenUri.ToString();
            this.dataGrid.ItemsSource = null;

            client.LoginList();

            this.btnLogin.IsEnabled = false;
            this.btnLogout.IsEnabled = true;
            this.btnSend.IsEnabled = true;
        }


        //退出
        private void btnLogout_Click(object sender, RoutedEventArgs e)
        {
            if (textBoxUserName.Text == String.Empty)
            {
                MessageBox.Show("用户名不能为空!!!");
                return;
            }
            client.Logout(UserName);
            userscount.Text = "在线人数:0";

            this.btnLogin.IsEnabled = true;
            this.btnLogout.IsEnabled = false;
            this.btnSend.IsEnabled = false;
        }

        //发送消息
        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            if (textBoxSend.Text == String.Empty)
            {
                MessageBox.Show("发送的消息不能为空!!!");
                return;
            }
            client.sendInfo(textBoxSend.Text, UserName);
            textBoxSend.Clear();
        }
        //显示用户登录
        public void ShowLogin(string loginUsername, int userCount)
        {
            listBoxMessage.Items.Add(loginUsername + "进入大厅。");
            userscount.Text = "在线人数:" + userCount.ToString();
        }
        //显示输入的消息
        public void ShowSendInfo(string info, string infousername)
        {
            listBoxMessage.Items.Add(infousername + ": " + info);
        }
        //显示用户退出
        public void ShowLogout(string userName, int userCount)
        {
            listBoxMessage.Items.Add(userName + "退出大厅。");
            userscount.Text = "在线人数:" + userCount.ToString();
            this.dataGrid.ItemsSource = null;
        }
        public void ShowWrongLogin(string username)
        {
            MessageBox.Show("用户" + username + "已经存在");
        }
        public void ShowWrongLogout(string username)
        {
            MessageBox.Show("用户" + username + "已经退出");
        }
        private void textBoxSend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                this.btnSend_Click(sender, e);
            }
        }

        //显示在线用户
        public void ShowUserList(User[] users)
        {
            this.dataGrid.ItemsSource = null;
            this.dataGrid.ItemsSource = users;

        }
        //私聊
        public void btnPrivateChat_Click(object sender, RoutedEventArgs e)
        {
            var temp = dataGrid.SelectedItem;
            if (temp == null)
            {
                return;
            }
            if (textBoxSend.Text == String.Empty)
            {
                MessageBox.Show("发送的消息不能为空!!!");
                return;
            }
            User SelectUser = temp as User;
            try
            {
                string SelectName = SelectUser.userName;
                client.PrivateChat(UserName, SelectName, textBoxSend.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "私发出现错误");
            }

        }
        public void ShowPrivateChat(string userName, string text)
        {
            listBoxMessage.Items.Add(userName + "发给你: " + text);
            textBoxSend.Clear();
        }


    }
}


MainWindow.xaml源码

<Window x:Class="WpfApp_ChatClient.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:WpfApp_ChatClient"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"></ColumnDefinition>
            <ColumnDefinition Width="500"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <DockPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Background="Cornsilk"
                   Margin="5 5 0 5">
            <Label Content="用户名:"/>
            <TextBox Name="textBoxUserName" Width="100" VerticalAlignment="Center"/>
            <Button Name="btnLogin" Content="登录" Width="60" Margin="10 0 10 0" Click="btnLogin_Click"/>
            <Button Name="btnLogout" Content="退出" Width="60" Margin="10 0 10 0" Click="btnLogout_Click"/>
            <TextBlock Name="serviceTextBlock" Text="服务端地址:" Margin="5 0 0 0" VerticalAlignment="Center"/>
        </DockPanel>
        <Grid Name="ChatRooms" Grid.Row="1" Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="20"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="聊天室" Background="Beige" TextAlignment="Center"></TextBlock>
            <Grid Grid.Row="1" >
                <ListBox Name="listBoxRooms" Background="AntiqueWhite" ScrollViewer.VerticalScrollBarVisibility="Visible"/>
            </Grid>
        </Grid>
        <Grid Name="chatRoom" Grid.Row="1" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="30"></RowDefinition>
            </Grid.RowDefinitions>
            <ListBox Name="listBoxMessage" Background="White" Grid.Row="0" ScrollViewer.VerticalScrollBarVisibility="Visible"/>
            <DockPanel Grid.Row="1" Background="AliceBlue" Margin="0 5 0 5" >
                <Button Name="btnPrivateChat" Content="私发" Margin="5 0 0 0" Width="80" Click="btnPrivateChat_Click"/>
                <TextBlock Text="聊天:" Margin="5 0 0 0 " DockPanel.Dock="Left" VerticalAlignment="Center"/>
                <Button Name="btnSend" Content="发送" Width="40" DockPanel.Dock="Right" Margin="5 0 5 0" Click="btnSend_Click"/>
                <TextBox Name="textBoxSend" KeyDown="textBoxSend_KeyDown"/>
            </DockPanel>
        </Grid>
        <Grid Name="chatUser" Grid.Row="1" Grid.Column="2">
            <Grid.RowDefinitions>
                <RowDefinition Height="20"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <TextBlock Name="userscount" Grid.Row="0" Text="在线人数: 0" Background="Beige" TextAlignment="Center"/>
            <DataGrid Name="dataGrid" Grid.Row="1" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding userName}" ClipboardContentBinding="{x:Null}" Header="在线用户"/>
                    <!-- <DataGridTextColumn Binding="{Binding loginTime}" ClipboardContentBinding="{x:Null}" Header="登录时间"/>-->
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
</Window>

界面如下

操作

 

 点击右侧在线用户,就可以私发消息

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nobor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值