套接字 OnConnectionLost 自定义事件
Socket OnConnectionLost Custom Event
我写了一个class本质上是一个心跳,客户端每隔x秒向服务器发送一条消息。
Shamelessly stolen Send code
private void SendUdpPacket() {
byte[] data = new byte[1024];
Socket udpClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
data = Encoding.ASCII.GetBytes("lubdub");
udpClientSocket.SendTo(data, 0, data.Length, SocketFlags.None, ipep);
}
Shamelessly stolen Receive code
void ReceiveData(IAsyncResult iar) {
byte[] buffer = new byte[1024];
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceiveFrom(iar, ref tempRemoteEP);
string stringData = Encoding.ASCII.GetString(buffer, 0, recv);
Console.WriteLine(stringData);
lastUpdate = DateTime.Now.ToUniversalTime();
if (!this.IsDisposed) {
udpServerSocket.BeginReceiveFrom(buffer, 0, 1024, SocketFlags.None, ref ep, new AsyncCallback(ReceiveData), udpServerSocket);
}
然后由内部计时器监控
private void clTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
try {
SendUdpPacket();
connected = true;
} catch {
connected = false;
}
}
private void srTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
// Calculate the Timespan since the Last Update from the Client.
timeSinceLastHeartbeat = DateTime.Now.ToUniversalTime() - lastUpdate;
if (timeSinceLastHeartbeat > TimeSpan.FromMilliseconds(Timer.Interval))
connected = false;
else
connected = true;
}
如果消息成功,则套接字已连接,这是通过 public 布尔值 connected
显示的
所以在我的应用程序中,我会有一个计时器 运行 以下内容:
private void ServerCheck() {
if (heartin.connected) {
GKstat = true;
GKStatus.Text = "GateKeeper Status: Connected";
} else {
GKstat = false;
GKStatus.Text = "GateKeeper Status: Disconnected";
}
}
但这并不理想,因为它需要客户端或服务器上的计时器不断检查 Heart
是否已连接。
我想知道将其转换为一组事件是否有益,
说 OnConnectionLost
和 OnConnected
我一直在四处寻找并阅读各种页面,它们只会让我更加困惑。
这是我目前所拥有的
public delegate void OnConnectionLost(Heart sender, EventArgs e);
public delegate void OnConnected(object sender, EventArgs e);
public event OnConnectionLost ConnectionLost;
我的问题是,这是否有益?如果有益,我将如何以仅在连接状态更改时触发的方式创建事件?
这是布尔值是邪恶的场景之一:我强烈建议你做一个 enum
例如:
public enum ConnectionState
{
Disconnected = 0,
Disconnecting = 1,
Connecting = 2,
Connected = 3,
// etc.
}
然后您可以将其用于 属性,例如 ConnectionState
。此外,通常的做法是使用标准 EventHandler<T>
委托而不是您自己的自定义委托类型。例如:
public sealed class ConnectionStateEventArgs : EventArgs
{
public ConnectionState ConnectionState { get; private set; }
public ConnectionStateEventArgs(ConnectionState connectionState)
{
ConnectionState = connectionState;
}
}
public event EventHandler<ConnectionStateEventArgs> ConnectionStateChanged;
这将使您能够将连接状态扩展到现有的简单 "on-off" 之外。 ConnectionState
属性 与 ConnectionStateChanged
事件相结合是我在各种 API 中注意到的常见做法。
要让它仅在连接状态 真正 发生变化时触发,只需将正文添加到您的 ConnectionState
属性:
private ConnectionState _connectionState;
public ConnectionState ConnectionState
{
get { return _connectionState; }
set
{
if (value != _connectionState)
{
_connectionState = value;
var tmp = ConnectionStateChanged;
if (tmp != null)
tmp (this, new ConnectionStateEventArgs(value));
}
}
}
然后您需要做的就是为 属性 分配一个不同的值,事件就会触发。
我写了一个class本质上是一个心跳,客户端每隔x秒向服务器发送一条消息。
Shamelessly stolen Send code
private void SendUdpPacket() {
byte[] data = new byte[1024];
Socket udpClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
data = Encoding.ASCII.GetBytes("lubdub");
udpClientSocket.SendTo(data, 0, data.Length, SocketFlags.None, ipep);
}
Shamelessly stolen Receive code
void ReceiveData(IAsyncResult iar) {
byte[] buffer = new byte[1024];
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceiveFrom(iar, ref tempRemoteEP);
string stringData = Encoding.ASCII.GetString(buffer, 0, recv);
Console.WriteLine(stringData);
lastUpdate = DateTime.Now.ToUniversalTime();
if (!this.IsDisposed) {
udpServerSocket.BeginReceiveFrom(buffer, 0, 1024, SocketFlags.None, ref ep, new AsyncCallback(ReceiveData), udpServerSocket);
}
然后由内部计时器监控
private void clTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
try {
SendUdpPacket();
connected = true;
} catch {
connected = false;
}
}
private void srTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
// Calculate the Timespan since the Last Update from the Client.
timeSinceLastHeartbeat = DateTime.Now.ToUniversalTime() - lastUpdate;
if (timeSinceLastHeartbeat > TimeSpan.FromMilliseconds(Timer.Interval))
connected = false;
else
connected = true;
}
如果消息成功,则套接字已连接,这是通过 public 布尔值 connected
所以在我的应用程序中,我会有一个计时器 运行 以下内容:
private void ServerCheck() {
if (heartin.connected) {
GKstat = true;
GKStatus.Text = "GateKeeper Status: Connected";
} else {
GKstat = false;
GKStatus.Text = "GateKeeper Status: Disconnected";
}
}
但这并不理想,因为它需要客户端或服务器上的计时器不断检查 Heart
是否已连接。
我想知道将其转换为一组事件是否有益,
说 OnConnectionLost
和 OnConnected
我一直在四处寻找并阅读各种页面,它们只会让我更加困惑。
这是我目前所拥有的
public delegate void OnConnectionLost(Heart sender, EventArgs e);
public delegate void OnConnected(object sender, EventArgs e);
public event OnConnectionLost ConnectionLost;
我的问题是,这是否有益?如果有益,我将如何以仅在连接状态更改时触发的方式创建事件?
这是布尔值是邪恶的场景之一:我强烈建议你做一个 enum
例如:
public enum ConnectionState
{
Disconnected = 0,
Disconnecting = 1,
Connecting = 2,
Connected = 3,
// etc.
}
然后您可以将其用于 属性,例如 ConnectionState
。此外,通常的做法是使用标准 EventHandler<T>
委托而不是您自己的自定义委托类型。例如:
public sealed class ConnectionStateEventArgs : EventArgs
{
public ConnectionState ConnectionState { get; private set; }
public ConnectionStateEventArgs(ConnectionState connectionState)
{
ConnectionState = connectionState;
}
}
public event EventHandler<ConnectionStateEventArgs> ConnectionStateChanged;
这将使您能够将连接状态扩展到现有的简单 "on-off" 之外。 ConnectionState
属性 与 ConnectionStateChanged
事件相结合是我在各种 API 中注意到的常见做法。
要让它仅在连接状态 真正 发生变化时触发,只需将正文添加到您的 ConnectionState
属性:
private ConnectionState _connectionState;
public ConnectionState ConnectionState
{
get { return _connectionState; }
set
{
if (value != _connectionState)
{
_connectionState = value;
var tmp = ConnectionStateChanged;
if (tmp != null)
tmp (this, new ConnectionStateEventArgs(value));
}
}
}
然后您需要做的就是为 属性 分配一个不同的值,事件就会触发。