Chẳng hạn như từ Server muốn gửi tín hiệu tới để đóng tất cả các Client, hay là hiển thị màn hỉnh cảnh báo
Hoặc từ 1 client nào đó, muốn gửi tín hiệu tới tất cả các client khác cũng như tới server thì làm như thế nào.
Ứng dụng sẽ cho phép chọn trên giao diện các chức năng sau:
1) – Gửi 1 thông báo nào đó tới toàn bộ client
2) – Gửi 1 thông báo nào đó tới 1 client nào đó
3) – Tắt toàn bộ chương trình Client
4) – Shutdown toàn bộ máy đang sử dụng chương trình Client
Ở đây Tôi sẽ kết hợp Timer để thiết lập trong khoảng thời gian bao nhiêu milisecond thì sẽ gửi/ nhận thông tin….
Giao diện của Server sẽ như sau:
Giao diện của Client:
Giao diện Send Message (khi Server chọn chức năng gửi thông báo thì các client sẽ tự động pop up giao diện này. Chỉ khi nào Active nó bằng cách bấm vào nút ở giữa màn hình thì nó không hiển thị):
Khi Server thực hiện các thao tác : (như hình minh họa) Thì client sẽ nhận được những thông tin tương Ứng
Ở đây còn 2 thao tác: Shutdown 1 máy client, Gửi thông điệp tới 1 client Tôi không làm, Tôi dành cho các bạn làm. Chú ý cách làm tương tự như Đóng cửa sổ từng client. Rất dễ, bạn chỉ cần chuyển đổi ProcessType (enum trong chương trình cho Tôi tạo) là bạn sẽ thực hiện được 2 yêu cầu này một cách dễ dàng.
Các bạn chú ý là chức năng Tắt client cũng như Shutdown từng máy client bạn nên hiển thị ListView cho phép chọn từng máy, hoặc chọn hết. Ở đây Tôi đã làm sẵn giao diện tắt từng client. bạn ứng dụng làm lại cho Shutdown.
Cấu trúc Solution:
Coding tầng ProxyObject – bạn để ý enum ProcessType, ứng với mỗi chức năng bạn chỉ cần đổi nó là ok:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ProxyObject
{
[Serializable]
public enum ProcessType
{
CLOSE_A_CLIENT_APPLICATION=100,
CLOSE_ALL_CLIENT_APPLICATION=101,
SEND_MESSAGE_TO_A_CLIENT = 102,
SEND_MESSAGE_TO_ALL_CLIENT = 103,
SHUTDOWN_A_CLIENT_COMPUTER = 104,
SHUTDOWN_ALL_CLIENT_COMPUTER = 105,
NONE=113
};
[Serializable]
public class ClientInfor
{
public string ClientName { get; set; }
public ProcessType Type { get; set; }
}
[Serializable]
public class MyProcess:MarshalByRefObject
{
private ArrayList listClient = new ArrayList();
public void addClient(ClientInfor client)
{
listClient.Add(client);
}
public void updateClientToClose(string clientName)
{
for (int i = 0; i < listClient.Count; i++)
{
ClientInfor c = listClient[i] as ClientInfor;
if (c.ClientName.Equals(clientName, StringComparison.CurrentCultureIgnoreCase))
{
c.Type = ProcessType.CLOSE_A_CLIENT_APPLICATION;
break;
}
}
}
public void removeAllClient()
{
listClient.Clear();
}
public void removeClient(ClientInfor client)
{
listClient.Remove(client);
}
public void removeClientByName(string name)
{
for (int i = 0; i < listClient.Count; i++)
{
ClientInfor c = listClient[i] as ClientInfor;
if (c.ClientName.Equals(name, StringComparison.CurrentCultureIgnoreCase))
{
listClient.RemoveAt(i);
break;
}
}
}
public ArrayList ListClient
{
get
{
return listClient;
}
}
public ProcessType Type { get; set; }
}
}
Coding tầng Server:
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using ProxyObject;
namespace ServerTier
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpChannel tcpChannel = null;
MyProcess myProcess = null;
private void btnStart_Click(object sender, EventArgs e)
{
int port = 9999;
if (Int32.TryParse(txtPort.Text,out port) == false)
{
MessageBox.Show(“Invalid Port!”);
txtPort.SelectAll();
txtPort.Focus();
}
if (tcpChannel != null || ChannelServices.GetChannel(“tcp”) != null)
{
ChannelServices.UnregisterChannel(tcpChannel);
}
tcpChannel = new TcpChannel(port);
ChannelServices.RegisterChannel(tcpChannel,false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyProcess), “MYPROCESS”, WellKnownObjectMode.Singleton);
Object o= Activator.GetObject(typeof(MyProcess), “tcp://localhost:” + port + “/MYPROCESS”);
if (o != null)
{
myProcess = o as MyProcess;
btnStart.Enabled = false;
this.Text = “Start OK”;
}
}private void btnCloseAllClientApplication_Click(object sender, EventArgs e)
{
myProcess.Type = ProcessType.CLOSE_ALL_CLIENT_APPLICATION;
}private void btnCloseAClientApplication_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.myProcess = myProcess;
frm2.ShowDialog();
}private void btnSendMessageToAClient_Click(object sender, EventArgs e)
{}private void btnShutdownAllClientComputer_Click(object sender, EventArgs e)
{
myProcess.Type = ProcessType.SHUTDOWN_ALL_CLIENT_COMPUTER;
}private void ShutdownAClientComputer_Click(object sender, EventArgs e)
{
}
private void btnSendMessageToAllClient_Click(object sender, EventArgs e)
{
myProcess.Type = ProcessType.SEND_MESSAGE_TO_ALL_CLIENT;
}
}
}
Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ProxyObject;
namespace ServerTier
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public MyProcess myProcess;
private void Form2_Load(object sender, EventArgs e)
{
listView1.Items.Clear();
foreach (ClientInfor client in myProcess.ListClient)
{
ListViewItem itm = new ListViewItem(client.ClientName);
itm.Tag = client;
listView1.Items.Add(itm);
}
}private void btnClose_Click(object sender, EventArgs e)
{
myProcess.Type = ProcessType.CLOSE_A_CLIENT_APPLICATION;
ListView.CheckedListViewItemCollection list = listView1.CheckedItems;
foreach (ListViewItem item in list)
{
ClientInfor client = item.Tag as ClientInfor;
myProcess.updateClientToClose(client.ClientName);
}
}
}
}
Coding tầng Client
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using ProxyObject;
namespace ClientTier
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
MyProcess myProcess = null;
Timer myTimer = null;
string myName=”x”;
public string getComputerName()
{
return System.Environment.MachineName +”-”+ System.DateTime.Now.Millisecond;
}
private void btnConnect_Click(object sender, EventArgs e)
{
string url=”tcp://”+txtServer.Text+”:”+txtPort.Text+”/MYPROCESS”;
RemotingConfiguration.RegisterWellKnownClientType(typeof(MyProcess),url);
myName = getComputerName();
myProcess = new MyProcess();
ClientInfor infor = new ClientInfor() { ClientName=myName,Type=ProcessType.NONE};
myProcess.addClient(infor);
frmMessage frmMsg = new frmMessage();
int isACK = -1;
myTimer = new Timer();
myTimer.Enabled = true;
myTimer.Interval = 300;
myTimer.Start();
myTimer.Tick += delegate
{
switch (myProcess.Type)
{
case ProcessType.CLOSE_A_CLIENT_APPLICATION:
foreach (ClientInfor client in myProcess.ListClient)
{
if (client.ClientName.Equals(myName, StringComparison.CurrentCultureIgnoreCase) && client.Type==ProcessType.CLOSE_A_CLIENT_APPLICATION)
{
Close();
myProcess.removeClientByName(myName);
}
}
break;
case ProcessType.CLOSE_ALL_CLIENT_APPLICATION:
Close();
myProcess.removeAllClient();
break;
case ProcessType.SEND_MESSAGE_TO_A_CLIENT:
break;
case ProcessType.SEND_MESSAGE_TO_ALL_CLIENT:
frmMsg.BackColor = Color.Red;
if (isACK==-1)
{
isACK = 0;
if (frmMsg.ShowDialog() == DialogResult.OK)
{
isACK = 1;
}
else
{
isACK = -1;
}
}
break;
case ProcessType.SHUTDOWN_A_CLIENT_COMPUTER:
foreach (ClientInfor client in myProcess.ListClient)
{
if (client.ClientName.Equals(myName, StringComparison.CurrentCultureIgnoreCase) && client.Type == ProcessType.SHUTDOWN_A_CLIENT_COMPUTER)
{
System.Diagnostics.Process.Start(“shutdown”, “/s /t 0″);
myProcess.removeClientByName(myName);
}
}
break;
case ProcessType.SHUTDOWN_ALL_CLIENT_COMPUTER:
System.Diagnostics.Process.Start(“shutdown”, “/s /t 0″);
myProcess.removeAllClient();
break;
}};
btnConnect.Enabled = false;
}private void Form1_Load(object sender, EventArgs e)
{
}
}
}
frmMessage.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace ClientTier
{
public partial class frmMessage : Form
{
public frmMessage()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
private void frmMessage_Load(object sender, EventArgs e)
{
}
}
}
Chúc các bạn thành công.