为什么我的wpf应用程序中的所有用户没有被列出

goqiplq2  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(115)

我用wpf应用程序做了一个聊天程序,但它没有列出连接的人,只有第一个连接的人出现在列表中。

这是我的代码。
MainWindow.xaml

<Window x:Class="WebSocketWpf.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:WebSocketWpf" xmlns:viewmodel="clr-namespace:Client.MVM.ViewModel"
        mc:Ignorable="d"
        Title="MainWindow" Height="455" Width="805">

    <Window.DataContext>
        <viewmodel:MainViewModel/>
    </Window.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <DockPanel>
            <TextBox Height="25"
                     DockPanel.Dock="Top"
                     Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Height="25"
                    DockPanel.Dock="Top"
                    Content="Bağlan"
                    Command="{Binding ConnectToServerCommand}"/>
            <ListView ItemsSource="{Binding Users}" SelectionChanged="ListView_SelectionChanged" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding UserName}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </DockPanel>

        <StackPanel Grid.Column="1">
            <ListView Height="380" Width="617"
            
                      ItemsSource="{Binding Messages}" />
            <StackPanel Orientation="Horizontal">
                <TextBox Height="55"
                         Width="545"                        
                         VerticalContentAlignment="Center"
                         Text="{Binding Message}" />
                <Button Width="55"
                        Content="Gönder"
                        Command="{Binding SendMessageCommand}"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

MainViewModel.cs

using Client.MVM.Core;
using Client.MVM.Model;
using Client.Net;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace Client.MVM.ViewModel
{
    class MainViewModel
    {

        public ObservableCollection<UserModel> Users { get; set; }

        public ObservableCollection<String> Messages { get; set; }

        public RelayCommand ConnectToServerCommand { get; set; }

        public RelayCommand SendMessageCommand { get; set; }

        public string Username { get; set; }

        public string Message { get; set; }

        private Server _server;
        
        public MainViewModel() 
        { 
            Users = new ObservableCollection<UserModel>();
            Messages = new ObservableCollection<string>();
            _server = new Server();
            _server.connectedEvent += UserConnected;
            _server.msgReceivedEvent += MessageReceived;
            _server.connectedEvent += RemoveUser;
            ConnectToServerCommand = new RelayCommand(o => _server.ConnectToServer(Username), o => !string.IsNullOrEmpty(Username));

            SendMessageCommand = new RelayCommand(o => _server.SendMessageToServer(Message), o => !string.IsNullOrEmpty(Message));

        }

        private void RemoveUser()
        {
            var uid = _server.PacketReader.ReadMessage();
            var user = Users.Where(x => x.UID == uid).FirstOrDefault();
            Application.Current.Dispatcher.Invoke(() => Users.Remove(user));
        }

        private void MessageReceived()
        {
            var msg = _server.PacketReader.ReadMessage();
            Application.Current.Dispatcher.Invoke(() => Messages.Add(msg));

        }
        private void UserConnected()

        {
            var user = new UserModel

            {
                 UserName = _server.PacketReader.ReadMessage(),
                 UID = _server.PacketReader.ReadMessage(),
            };

            if (!Users.Any(x => x.UID == user.UID))
            {
                Application.Current.Dispatcher.Invoke(() => Users.Add(user));
            }
        }

    }
}

UserModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Client.MVM.Model
{
    class UserModel
    {

        public string UserName { get; set; }   
        public string UID { get; set; }
    }
}

服务器
Program.cs

using Client.Net.IO;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    class Program
    {

        static List<Client> _users;
       static TcpListener _listener;
        static void Main(string[] args)
        {
            _users = new List<Client>();
            _listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 7891);
            _listener.Start();

            while (true)
            {

                var client = new Client(_listener.AcceptTcpClient());
                Console.WriteLine("İstemci başarıyla bağlandı!");
                _users.Add(client);

                BroadcastConnection();

            }

        }

        static void BroadcastConnection()
        {
            foreach (var user in _users)
            {

                foreach (var usr in _users)
                {

                    var broadcastPacket = new PacketBuilder();
                    broadcastPacket.WriteOpCode(1);
                    broadcastPacket.WriteMessage(usr.Username);
                    broadcastPacket.WriteMessage(usr.UID.ToString());
                    user.ClientSocket.Client.Send(broadcastPacket.GetPacketBytes());
                }
            }
        }

        public static void BroadcastMessage(string message)
        {
            foreach (var user in _users)

            {
                var msgPacket = new PacketBuilder();
                msgPacket.WriteOpCode(5);
                msgPacket.WriteMessage(message);
                user.ClientSocket.Client.Send(msgPacket.GetPacketBytes());
            }
        }

        public static void BroadcastDisconnect(string uid)
        {
            var disconnectedUser = _users.Where(x => x.UID.ToString() == uid).FirstOrDefault();
            _users.Remove(disconnectedUser);
            foreach (var user in _users)

            {
                var broadcastPacket = new PacketBuilder();
                broadcastPacket.WriteOpCode(10);
                broadcastPacket.WriteMessage(uid);
                user.ClientSocket.Client.Send(broadcastPacket.GetPacketBytes());
            }

            BroadcastMessage($"[{disconnectedUser.Username}] Bağlantı Kesildi");
        }
    }
}

例如,当从2个客户端连接时,两个人都需要在左角写上他们的名字。但只有一个客户的名字在名单上。

nuypyhwy

nuypyhwy1#

我认为你的问题是在UserConnected()RemoveUser()事件处理程序中。
您访问的User集合不在Dispatcher中。

private void UserConnected()
{
    var user = new UserModel
    {
        UserName = _server.PacketReader.ReadMessage(),
        UID = _server.PacketReader.ReadMessage(),
    };
    Application.Current.Dispatcher.Invoke(() =>
    {
        if (!Users.Any(x => x.UID == user.UID))
        {
            Users.Add(user);
        }
    });
}

相关问题