c#网编实验五 您所在的位置:网站首页 wcf跨平台 c#网编实验五

c#网编实验五

2023-06-19 07:52| 来源: 网络整理| 查看: 265

分别编写服务端和客户端程序,利用基于WCF的TCP技术,实现在线聊天功能,完成在线用户列表管理,消息发送、接收的功能。

在同一个解决方案中,分别编写服务端程序和客户端程序,利用TCP实现简单的群聊功能。

 

 

具体要求如下: (1)服务端程序选择【WCF服务库】模板,客户端程序选择【WPF应用程序】模板。 (2)客户端与服务端连接成功后,通过服务端获取已经在线的用户,并将其显示在客户端的在线用户列表中。 (3)不论哪个用户发送聊天消息,其他所有用户都能看到该消息。 (4)当某个用户退出后,在线用户列表中自动移除该用户。  

重点:

(1)掌握TCP协议下WCF服务应用程序构建方法。 (2)掌握客户端和服务端通信接口设计方法。 (3)掌握协定的设计及实现方法。 (4)掌握双工通信的设计及实现方法。 (5)熟悉WCF和TCP的相关绑定设置。 难点:

(1)掌握客户端和服务端通信接口设计方法。 (2)掌握协定的设计及实现方法。 (3)掌握双工通信的设计及实现方法。 (4)熟悉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 ChatClient { /// /// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void btn1_Click(object sender, RoutedEventArgs e) { StartWindow("西西皮", 50, 300); StartWindow("瓜瓜糖", 600, 300); } private void StartWindow(string userName, int left, int top) { ClientWindow w = new ClientWindow(); w.Left = left; w.Top = top; w.UserName = userName; w.Owner = this; w.Closed += (sender, e) => this.Activate(); w.Show(); } private void btn2_Click(object sender, RoutedEventArgs e) { ClientWindow w = new ClientWindow(); w.Owner = this; w.Closed += (sendObj, args) => this.Activate(); w.Show(); } } }

ClientWindow.xaml  

 

ClientWindow.xaml.cs using System; using System.Collections.Generic; 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; using ChatClient.ChatServiceReference; namespace ChatClient { /// /// ClientWindow.xaml 的交互逻辑 /// public partial class ClientWindow : Window, IChatServiceCallback { public ClientWindow() { InitializeComponent(); this.Closing += ClientWindow_Closing; dockPanel1.Visibility = System.Windows.Visibility.Hidden; } public string UserName { get { return textBoxUserName.Text; } set { textBoxUserName.Text = value; } } private ChatServiceClient client; void ClientWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (client != null) { client.Logout(UserName); //退出 client.Close(); } } private void AddMessage(string str) { TextBlock t = new TextBlock(); t.Text = str; t.Foreground = Brushes.Blue; listBoxMessage.Items.Add(t); } //单击登录按钮引发的事件 private void btnLogin_Click(object sender, RoutedEventArgs e) { this.Cursor = Cursors.Wait; UserName = textBoxUserName.Text; InstanceContext context = new InstanceContext(this); client = new ChatServiceReference.ChatServiceClient(context); try { client.Login(textBoxUserName.Text); btnLogin.IsEnabled = false; } catch (Exception ex) { MessageBox.Show("与服务端连接失败:" + ex.Message); return; } this.Cursor = Cursors.Arrow; } //单击发送按钮引发的事件 private void btnSend_Click(object sender, RoutedEventArgs e) { client.Talk(UserName, textBoxTalk.Text); textBoxTalk.Text = ""; } //在文本框中输入对话后按回车键时引发的事件 private void textBoxTalk_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { client.Talk(UserName, textBoxTalk.Text); textBoxTalk.Text = ""; } } #region 实现IRndGameServiceCallback接口 /// 有用户登录 public void ShowLogin(string loginUserName) { if (loginUserName == UserName) { dockPanel1.Visibility = System.Windows.Visibility.Visible; } listBoxOnLine.Items.Add(loginUserName); } /// 其他用户退出 public void ShowLogout(string userName) { listBoxOnLine.Items.Remove(userName); } public void ShowTalk(string userName, string message) { AddMessage(string.Format("[{0}]说:{1}", userName, message)); } public void InitUsersInfo(string UsersInfo) { if (UsersInfo.Length == 0) return; string[] users=UsersInfo.Split('、'); for (int i = 0; i < users.Length; i++) { listBoxOnLine.Items.Add(users[i]); } } #endregion } }

服务端 IChatService.cs using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace ChatServer { //需要服务端实现的协定 [ServiceContract(Namespace = "WcfChatExample", CallbackContract = typeof(IChatServiceCallback))] public interface IChatService { [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 IChatServiceCallback { [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); } }  

 

 ChatService.cs

using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace ChatServer { public class ChatService : IChatService { /// /// 用户退出。参数:登录者用户名 /// public void Login(string userName) { OperationContext context = OperationContext.Current; IChatServiceCallback callback = context.GetCallbackChannel(); User newUser = new User(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) { User logoutUser = CC.GetUser(userName); CC.Users.Remove(logoutUser); logoutUser = null; //将其设置为null后,WCF会自动关闭该客户端 foreach (var user in CC.Users) { user.callback.ShowLogout(userName); } } /// /// 客户端发来的对话信息。参数:发送者用户名,对话内容 /// public void Talk(string userName, string message) { User user = CC.GetUser(userName); foreach (var v in CC.Users) { v.callback.ShowTalk(userName, message); } } } }

User.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ChatServer { public class User { public string UserName { get; set; } public readonly IChatServiceCallback callback; public User(string userName, IChatServiceCallback 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 ChatServer { public class CC { //连接的用户,每个用户都对应一个ChatService线程 public static List Users { get; set; } static CC() { Users = new List(); } public static User GetUser(string userName) { User user = null; foreach (var v in Users) { if (v.UserName == userName) { user = v; break; } } return user; } } }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有