我用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个客户端连接时,两个人都需要在左角写上他们的名字。但只有一个客户的名字在名单上。
1条答案
按热度按时间nuypyhwy1#
我认为你的问题是在
UserConnected()
和RemoveUser()
事件处理程序中。您访问的
User
集合不在Dispatcher
中。