FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add simple protocol client example · bug8975/NetCoreServer@3556e42 · GitHub

Repository navigation

Commit 3556e42

Browse files
committed
Add simple protocol client example
1 parent 6b9ec4a commit 3556e42

11 files changed

Lines changed: 507 additions & 48 deletions

File tree

‎NetCoreServer.sln‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "proto", "proto", "{7535CE12
109109
EndProject
110110
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "proto", "proto\proto.csproj", "{0A31A021-B53C-4B1B-A408-A46ABC97C93F}"
111111
EndProject
112+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProtoClient", "examples\ProtoClient\ProtoClient.csproj", "{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}"
113+
EndProject
112114
Global
113115
GlobalSection(SolutionConfigurationPlatforms) = preSolution
114116
Debug|Any CPU = Debug|Any CPU
@@ -509,6 +511,14 @@ Global
509511
{0A31A021-B53C-4B1B-A408-A46ABC97C93F}.Release|Any CPU.Build.0 = Release|Any CPU
510512
{0A31A021-B53C-4B1B-A408-A46ABC97C93F}.Release|x64.ActiveCfg = Release|Any CPU
511513
{0A31A021-B53C-4B1B-A408-A46ABC97C93F}.Release|x64.Build.0 = Release|Any CPU
514+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
515+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Debug|Any CPU.Build.0 = Debug|Any CPU
516+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Debug|x64.ActiveCfg = Debug|Any CPU
517+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Debug|x64.Build.0 = Debug|Any CPU
518+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Release|Any CPU.ActiveCfg = Release|Any CPU
519+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Release|Any CPU.Build.0 = Release|Any CPU
520+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Release|x64.ActiveCfg = Release|Any CPU
521+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F}.Release|x64.Build.0 = Release|Any CPU
512522
EndGlobalSection
513523
GlobalSection(SolutionProperties) = preSolution
514524
HideSolutionNode = FALSE
@@ -562,6 +572,7 @@ Global
562572
{B1D5EA8F-9A1E-4AD6-9C40-A6A5EFDDE044} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
563573
{80C95510-AF12-4CF0-8852-B21241F6C1F3} = {8965E5CD-E36E-4DC5-A36E-827AFFC642D1}
564574
{0A31A021-B53C-4B1B-A408-A46ABC97C93F} = {7535CE12-3B22-4473-890A-980B72E5D27A}
575+
{6F0566A8-39A6-4910-BBE9-8F0B2CAEF50F} = {81ED94B5-0C65-432C-AEF5-67C3DFF7F2EE}
565576
EndGlobalSection
566577
GlobalSection(ExtensibilityGlobals) = postSolution
567578
SolutionGuid = {64415837-63D9-474E-A25C-EE91C9CA90C5}

‎examples/ProtoClient/Program.cs‎

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
using System;
2+
using System.Net.Sockets;
3+
using System.Threading;
4+
using TcpClient = NetCoreServer.TcpClient;
5+
6+
namespace TcpChatClient
7+
{
8+
public class TcpProtoClient : TcpClient
9+
{
10+
public TcpProtoClient(string address, int port) : base(address, port) {}
11+
12+
public bool ConnectAndStart()
13+
{
14+
Console.WriteLine($"TCP protocol client starting a new session with Id '{Id}'...");
15+
16+
StartReconnectTimer();
17+
return ConnectAsync();
18+
}
19+
20+
public bool DisconnectAndStop()
21+
{
22+
Console.WriteLine($"TCP protocol client stopping the session with Id '{Id}'...");
23+
24+
StopReconnectTimer();
25+
DisconnectAsync();
26+
return true;
27+
}
28+
29+
public override bool Reconnect()
30+
{
31+
return ReconnectAsync();
32+
}
33+
34+
private Timer _reconnectTimer;
35+
36+
public void StartReconnectTimer()
37+
{
38+
// Start the reconnect timer
39+
_reconnectTimer = new Timer(state =>
40+
{
41+
Console.WriteLine($"TCP reconnect timer connecting the client session with Id '{Id}'...");
42+
ConnectAsync();
43+
}, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
44+
}
45+
46+
public void StopReconnectTimer()
47+
{
48+
// Stop the reconnect timer
49+
_reconnectTimer?.Dispose();
50+
_reconnectTimer = null;
51+
}
52+
53+
public delegate void ConnectedHandler();
54+
public event ConnectedHandler Connected = () => {};
55+
56+
protected override void OnConnected()
57+
{
58+
Console.WriteLine($"TCP protocol client connected a new session with Id '{Id}' to remote address '{Address}' and port {Port}");
59+
60+
Connected?.Invoke();
61+
}
62+
63+
public delegate void DisconnectedHandler();
64+
public event DisconnectedHandler Disconnected = () => {};
65+
66+
protected override void OnDisconnected()
67+
{
68+
Console.WriteLine($"TCP protocol client disconnected the session with Id '{Id}'");
69+
70+
// Setup and asynchronously wait for the reconnect timer
71+
_reconnectTimer?.Change(TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan);
72+
73+
Disconnected?.Invoke();
74+
}
75+
76+
public delegate void ReceivedHandler(byte[] buffer, long offset, long size);
77+
public event ReceivedHandler Received = (buffer, offset, size) => {};
78+
79+
protected override void OnReceived(byte[] buffer, long offset, long size)
80+
{
81+
Received?.Invoke(buffer, offset, size);
82+
}
83+
84+
protected override void OnError(SocketError error)
85+
{
86+
Console.WriteLine($"TCP protocol client caught a socket error: {error}");
87+
}
88+
89+
#region IDisposable implementation
90+
91+
// Disposed flag.
92+
private bool _disposed;
93+
94+
protected override void Dispose(bool disposingManagedResources)
95+
{
96+
if (!_disposed)
97+
{
98+
if (disposingManagedResources)
99+
{
100+
// Dispose managed resources here...
101+
StopReconnectTimer();
102+
}
103+
104+
// Dispose unmanaged resources here...
105+
106+
// Set large fields to null here...
107+
108+
// Mark as disposed.
109+
_disposed = true;
110+
}
111+
112+
// Call Dispose in the base class.
113+
base.Dispose(disposingManagedResources);
114+
}
115+
116+
// The derived class does not have a Finalize method
117+
// or a Dispose method without parameters because it inherits
118+
// them from the base class.
119+
120+
#endregion
121+
}
122+
123+
public class SimpleProtoClient : FBE.simple.Client, FBE.simple.ISenderListener, FBE.simple.IReceiverListener, IDisposable
124+
{
125+
private readonly TcpProtoClient _tcpProtoClient;
126+
127+
public Guid Id => _tcpProtoClient.Id;
128+
public bool IsConnected => _tcpProtoClient.IsConnected;
129+
130+
public SimpleProtoClient(string address, int port)
131+
{
132+
_tcpProtoClient = new TcpProtoClient(address, port);
133+
_tcpProtoClient.Connected += OnConnected;
134+
_tcpProtoClient.Disconnected += OnDisconnected;
135+
_tcpProtoClient.Received += OnReceived;
136+
ReceivedResponse_DisconnectRequest += HandleDisconnectRequest;
137+
ReceivedResponse_SimpleResponse += HandleSimpleResponse;
138+
ReceivedResponse_SimpleReject += HandleSimpleReject;
139+
ReceivedResponse_SimpleNotify += HandleSimpleNotify;
140+
}
141+
142+
private void DisposeClient()
143+
{
144+
_tcpProtoClient.Connected -= OnConnected;
145+
_tcpProtoClient.Connected -= OnDisconnected;
146+
_tcpProtoClient.Received -= OnReceived;
147+
ReceivedResponse_DisconnectRequest -= HandleDisconnectRequest;
148+
ReceivedResponse_SimpleResponse -= HandleSimpleResponse;
149+
ReceivedResponse_SimpleReject -= HandleSimpleReject;
150+
ReceivedResponse_SimpleNotify -= HandleSimpleNotify;
151+
_tcpProtoClient.Dispose();
152+
}
153+
154+
public bool ConnectAndStart() { return _tcpProtoClient.ConnectAndStart(); }
155+
public bool DisconnectAndStop() { return _tcpProtoClient.DisconnectAndStop(); }
156+
public bool Reconnect() { return _tcpProtoClient.Reconnect(); }
157+
158+
private bool _watchdog;
159+
private Thread _watchdogThread;
160+
161+
public bool StartWatchdog()
162+
{
163+
if (_watchdog)
164+
return false;
165+
166+
Console.WriteLine("Watchdog thread starting...");
167+
168+
// Start the watchdog thread
169+
_watchdog = true;
170+
_watchdogThread = new Thread(WatchdogThread);
171+
172+
Console.WriteLine("Watchdog thread started!");
173+
174+
return true;
175+
}
176+
177+
public bool StopWatchdog()
178+
{
179+
if (!_watchdog)
180+
return false;
181+
182+
Console.WriteLine("Watchdog thread stopping...");
183+
184+
// Stop the watchdog thread
185+
_watchdog = false;
186+
_watchdogThread.Join();
187+
188+
Console.WriteLine("Watchdog thread stopped!");
189+
190+
return true;
191+
}
192+
193+
public static void WatchdogThread(object obj)
194+
{
195+
var instance = obj as SimpleProtoClient;
196+
if (instance == null)
197+
return;
198+
199+
try
200+
{
201+
// Watchdog loop...
202+
while (instance._watchdog)
203+
{
204+
var utc = DateTime.UtcNow;
205+
206+
// Watchdog the client
207+
instance.Watchdog(utc);
208+
209+
// Sleep for a while...
210+
Thread.Sleep(1000);
211+
}
212+
}
213+
catch (Exception e)
214+
{
215+
Console.WriteLine($"Config client watchdog thread terminated: {e}");
216+
}
217+
}
218+
219+
#region Connection handlers
220+
221+
public delegate void ConnectedHandler();
222+
public event ConnectedHandler Connected = () => {};
223+
224+
private void OnConnected()
225+
{
226+
// Reset FBE protocol buffers
227+
Reset();
228+
229+
Connected?.Invoke();
230+
}
231+
232+
public delegate void DisconnectedHandler();
233+
public event DisconnectedHandler Disconnected = () => {};
234+
235+
private void OnDisconnected()
236+
{
237+
Disconnected?.Invoke();
238+
}
239+
240+
public long OnSend(byte[] buffer, long offset, long size)
241+
{
242+
return _tcpProtoClient.SendAsync(buffer, offset, size) ? size : 0;
243+
}
244+
245+
public void OnReceived(byte[] buffer, long offset, long size)
246+
{
247+
Receive(buffer, offset, size);
248+
}
249+
250+
#endregion
251+
252+
#region Protocol handlers
253+
254+
private void HandleDisconnectRequest(simple.DisconnectRequest request) { Console.WriteLine($"Received: {request}"); _tcpProtoClient.DisconnectAsync(); }
255+
private void HandleSimpleResponse(simple.SimpleResponse response) { Console.WriteLine($"Received: {response}"); }
256+
private void HandleSimpleReject(simple.SimpleReject reject) { Console.WriteLine($"Received: {reject}"); }
257+
private void HandleSimpleNotify(simple.SimpleNotify notify) { Console.WriteLine($"Received: {notify}"); }
258+
259+
#endregion
260+
261+
#region IDisposable implementation
262+
263+
// Disposed flag.
264+
private bool _disposed;
265+
266+
// Implement IDisposable.
267+
public void Dispose()
268+
{
269+
Dispose(true);
270+
GC.SuppressFinalize(this);
271+
}
272+
273+
protected virtual void Dispose(bool disposingManagedResources)
274+
{
275+
// The idea here is that Dispose(Boolean) knows whether it is
276+
// being called to do explicit cleanup (the Boolean is true)
277+
// versus being called due to a garbage collection (the Boolean
278+
// is false). This distinction is useful because, when being
279+
// disposed explicitly, the Dispose(Boolean) method can safely
280+
// execute code using reference type fields that refer to other
281+
// objects knowing for sure that these other objects have not been
282+
// finalized or disposed of yet. When the Boolean is false,
283+
// the Dispose(Boolean) method should not execute code that
284+
// refer to reference type fields because those objects may
285+
// have already been finalized."
286+
287+
if (!_disposed)
288+
{
289+
if (disposingManagedResources)
290+
{
291+
// Dispose managed resources here...
292+
DisposeClient();
293+
}
294+
295+
// Dispose unmanaged resources here...
296+
297+
// Set large fields to null here...
298+
299+
// Mark as disposed.
300+
_disposed = true;
301+
}
302+
}
303+
304+
#endregion
305+
}
306+
307+
class Program
308+
{
309+
static void Main(string[] args)
310+
{
311+
// Simple protocol server address
312+
string address = "127.0.0.1";
313+
if (args.Length > 0)
314+
address = args[0];
315+
316+
// Simple protocol server port
317+
int port = 4444;
318+
if (args.Length > 1)
319+
port = int.Parse(args[1]);
320+
321+
Console.WriteLine($"Simple protocol server address: {address}");
322+
Console.WriteLine($"Simple protocol server port: {port}");
323+
324+
Console.WriteLine();
325+
326+
// Create a new simple protocol chat client
327+
var client = new SimpleProtoClient(address, port);
328+
329+
// Connect the client
330+
Console.Write("Client connecting...");
331+
client.ConnectAndStart();
332+
Console.WriteLine("Done!");
333+
334+
Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");
335+
336+
// Perform text input
337+
for (;;)
338+
{
339+
string line = Console.ReadLine();
340+
if (string.IsNullOrEmpty(line))
341+
break;
342+
343+
// Disconnect the client
344+
if (line == "!")
345+
{
346+
Console.Write("Client disconnecting...");
347+
client.Reconnect();
348+
Console.WriteLine("Done!");
349+
continue;
350+
}
351+
352+
// Send request to the simple protocol server
353+
simple.SimpleRequest request = simple.SimpleRequest.Default;
354+
request.Message = line;
355+
var response = client.Request(request).Result;
356+
357+
// Show string hash calculation result
358+
Console.WriteLine($"Hash of '{line}' = 0x{response.Hash:X8}");
359+
}
360+
361+
// Disconnect the client
362+
Console.Write("Client disconnecting...");
363+
client.DisconnectAndStop();
364+
Console.WriteLine("Done!");
365+
}
366+
}
367+
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL