Skip to content

Commit 0dc4b97

Browse files
authored
Merge pull request #37 from re-cheid/ping
Fixed ping and heartbeat issue when receiving lots of messages [.NET 3.5]
2 parents a9f185d + 41400a3 commit 0dc4b97

File tree

4 files changed

+137
-19
lines changed

4 files changed

+137
-19
lines changed

Src/EngineIoClientDotNet.mono/Client/Socket_net35.cs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ private enum ReadyStateEnum
6363
private Dictionary<string, string> Cookies = new Dictionary<string, string>();
6464
/*package*/
6565
public Transport Transport;
66-
private EasyTimer PingTimeoutTimer;
67-
private EasyTimer PingIntervalTimer;
66+
private Heartbeat HeartbeatTimer;
67+
private TriggeredLoopTimer PingIntervalTimer;
6868

6969
private ReadyStateEnum ReadyState;
7070
private bool Agent = false;
@@ -474,7 +474,7 @@ public void OnPacket(Packet packet)
474474
}
475475
else if (packet.Type == Packet.PONG)
476476
{
477-
this.SetPing();
477+
PingIntervalTimer.Trigger();
478478
}
479479
else if (packet.Type == Packet.ERROR)
480480
{
@@ -529,7 +529,7 @@ public OnHeartbeatAsListener(Socket socket)
529529

530530
void IListener.Call(params object[] args)
531531
{
532-
socket.OnHeartbeat(args.Length > 0 ? (long)args[0] : 0);
532+
socket.OnHeartbeat();
533533
}
534534

535535
public int CompareTo(IListener other)
@@ -549,20 +549,16 @@ private void SetPing()
549549
{
550550
//var log = LogManager.GetLogger(Global.CallerName());
551551

552-
if (this.PingIntervalTimer != null)
553-
{
554-
PingIntervalTimer.Stop();
555-
}
556552
var log = LogManager.GetLogger(Global.CallerName());
557553
log.Info(string.Format("writing ping packet - expecting pong within {0}ms", PingTimeout));
558554

559-
PingIntervalTimer = EasyTimer.SetTimeout(() =>
555+
PingIntervalTimer = TriggeredLoopTimer.Start(() =>
560556
{
561557
var log2 = LogManager.GetLogger(Global.CallerName());
562558
log2.Info("EasyTimer SetPing start");
563559

564560
Ping();
565-
OnHeartbeat(PingTimeout);
561+
SetHeartbeat(PingTimeout);
566562
log2.Info("EasyTimer SetPing finish");
567563
}, (int)PingInterval);
568564
}
@@ -1056,9 +1052,9 @@ private void OnClose(string reason, Exception desc = null)
10561052
{
10571053
this.PingIntervalTimer.Stop();
10581054
}
1059-
if (this.PingTimeoutTimer != null)
1055+
if (this.HeartbeatTimer != null)
10601056
{
1061-
this.PingTimeoutTimer.Stop();
1057+
this.HeartbeatTimer.Stop();
10621058
}
10631059

10641060

@@ -1113,22 +1109,22 @@ public List<string> FilterUpgrades(IEnumerable<string> upgrades)
11131109
return filterUpgrades;
11141110
}
11151111

1116-
1117-
1118-
internal void OnHeartbeat(long timeout)
1112+
internal void OnHeartbeat()
11191113
{
1120-
if (this.PingTimeoutTimer != null)
1114+
if(this.HeartbeatTimer != null)
11211115
{
1122-
PingTimeoutTimer.Stop();
1123-
PingTimeoutTimer = null;
1116+
this.HeartbeatTimer.OnHeartbeat();
11241117
}
1118+
}
11251119

1120+
internal void SetHeartbeat(long timeout)
1121+
{
11261122
if (timeout <= 0)
11271123
{
11281124
timeout = this.PingInterval + this.PingTimeout;
11291125
}
11301126

1131-
PingTimeoutTimer = EasyTimer.SetTimeout(() =>
1127+
HeartbeatTimer = Heartbeat.Start (() =>
11321128
{
11331129
var log2 = LogManager.GetLogger(Global.CallerName());
11341130
log2.Info("EasyTimer OnHeartbeat start");
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Threading;
4+
5+
namespace Quobject.EngineIoClientDotNet.Thread
6+
{
7+
public class Heartbeat
8+
{
9+
private volatile bool gotHeartbeat = false;
10+
private BackgroundWorker heartBeatTimer;
11+
private CancellationTokenSource ts;
12+
13+
private Heartbeat()
14+
{
15+
ts = new CancellationTokenSource();
16+
}
17+
18+
public static Heartbeat Start(Action onTimeout, int timeout)
19+
{
20+
Heartbeat heartbeat = new Heartbeat();
21+
heartbeat.Run(onTimeout, timeout);
22+
return heartbeat;
23+
}
24+
25+
public void OnHeartbeat()
26+
{
27+
gotHeartbeat = true;
28+
}
29+
30+
private void Run(Action onTimeout, int timeout)
31+
{
32+
heartBeatTimer = new BackgroundWorker();
33+
34+
heartBeatTimer.DoWork += (s, e) =>
35+
{
36+
while (!ts.IsCancellationRequested)
37+
{
38+
System.Threading.Thread.Sleep(timeout);
39+
if (!gotHeartbeat && !ts.IsCancellationRequested)
40+
{
41+
onTimeout();
42+
break;
43+
}
44+
}
45+
};
46+
47+
heartBeatTimer.RunWorkerAsync();
48+
}
49+
50+
public void Stop()
51+
{
52+
ts.Cancel();
53+
}
54+
}
55+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Threading;
4+
5+
namespace Quobject.EngineIoClientDotNet.Thread
6+
{
7+
public class TriggeredLoopTimer
8+
{
9+
private ManualResetEvent trigger;
10+
private CancellationTokenSource ts;
11+
12+
private TriggeredLoopTimer()
13+
{
14+
trigger = new ManualResetEvent(false);
15+
ts = new CancellationTokenSource();
16+
}
17+
18+
public static TriggeredLoopTimer Start (Action method, int delayInMilliseconds)
19+
{
20+
TriggeredLoopTimer ping = new TriggeredLoopTimer();
21+
ping.Run (method, delayInMilliseconds);
22+
return ping;
23+
}
24+
25+
26+
public void Trigger()
27+
{
28+
trigger.Set();
29+
}
30+
31+
private void Run (Action method, int delayInMilliseconds)
32+
{
33+
var worker = new BackgroundWorker();
34+
35+
worker.DoWork += (s, e) =>
36+
{
37+
while (!ts.IsCancellationRequested)
38+
{
39+
System.Threading.Thread.Sleep (delayInMilliseconds);
40+
if (!ts.IsCancellationRequested)
41+
{
42+
method();
43+
trigger.WaitOne();
44+
trigger.Reset();
45+
}
46+
}
47+
};
48+
49+
worker.RunWorkerAsync();
50+
}
51+
52+
public void Stop()
53+
{
54+
if (ts != null)
55+
{
56+
ts.Cancel();
57+
trigger.Set();
58+
}
59+
}
60+
}
61+
}

Src/EngineIoClientDotNet.net35/EngineIoClientDotNet.net35.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@
115115
<Compile Include="..\EngineIoClientDotNet.mono\Thread\EasyTimer_net35.cs">
116116
<Link>Thread\EasyTimer_net35.cs</Link>
117117
</Compile>
118+
<Compile Include="..\EngineIoClientDotNet.mono\Thread\Heartbeat_net35.cs">
119+
<Link>Thread\Heartbeat_net35.cs</Link>
120+
</Compile>
121+
<Compile Include="..\EngineIoClientDotNet.mono\Thread\TriggeredLoopTimer_net35.cs">
122+
<Link>Thread\TriggeredLoopTimer_net35.cs</Link>
123+
</Compile>
118124
<Compile Include="Parser\Packet_net35.cs" />
119125
<Compile Include="Properties\AssemblyInfo.cs" />
120126
</ItemGroup>

0 commit comments

Comments
 (0)