33using FaasNet . EventMesh . Client . Messages ;
44using FaasNet . RaftConsensus . Client ;
55using FaasNet . RaftConsensus . Client . Extensions ;
6+ using FaasNet . RaftConsensus . Client . Messages ;
67using System ;
78using System . Collections . Generic ;
89using System . Linq ;
@@ -59,15 +60,15 @@ public EventMeshClient(string url = Constants.DefaultUrl, int port = Constants.D
5960 }
6061 }
6162
62- public async Task < IEventMeshClientPubSession > CreatePubSession ( string clientId , CancellationToken cancellationToken = default ( CancellationToken ) )
63+ public async Task < IEventMeshClientPubSession > CreatePubSession ( string vpn , string clientId , CancellationToken cancellationToken = default ( CancellationToken ) )
6364 {
64- var pubSession = await CreateSession ( clientId , cancellationToken ) ;
65+ var pubSession = await CreateSession ( vpn , clientId , UserAgentPurpose . PUB , cancellationToken ) ;
6566 return new EventMeshClientPubSession ( pubSession , _ipAddr , _port ) ;
6667 }
6768
68- public async Task < IEventMeshClientSubSession > CreateSubSession ( string clientId , CancellationToken cancellationToken = default ( CancellationToken ) )
69+ public async Task < IEventMeshClientSubSession > CreateSubSession ( string vpn , string clientId , CancellationToken cancellationToken = default ( CancellationToken ) )
6970 {
70- var subSession = await CreateSession ( clientId , cancellationToken ) ;
71+ var subSession = await CreateSession ( vpn , clientId , UserAgentPurpose . SUB , cancellationToken ) ;
7172 return new EventMeshClientSubSession ( subSession , _ipAddr , _port ) ;
7273 }
7374
@@ -87,12 +88,12 @@ public EventMeshClient(string url = Constants.DefaultUrl, int port = Constants.D
8788 }
8889 }
8990
90- public async Task AddClient ( string vpn , string clientId , CancellationToken cancellationToken = default ( CancellationToken ) )
91+ public async Task AddClient ( string vpn , string clientId , List < UserAgentPurpose > purposes , CancellationToken cancellationToken = default ( CancellationToken ) )
9192 {
9293 using ( var udpClient = new UdpClient ( ) )
9394 {
9495 var writeCtx = new WriteBufferContext ( ) ;
95- var package = PackageRequestBuilder . AddClient ( vpn , clientId ) ;
96+ var package = PackageRequestBuilder . AddClient ( vpn , clientId , purposes ) ;
9697 package . Serialize ( writeCtx ) ;
9798 var payload = writeCtx . Buffer . ToArray ( ) ;
9899 await udpClient . SendAsync ( payload , payload . Count ( ) , new IPEndPoint ( _ipAddr , _port ) ) . WithCancellation ( cancellationToken ) ;
@@ -116,9 +117,9 @@ internal static void EnsureSuccessStatus(Package packageRequest, Package package
116117 }
117118 }
118119
119- private async Task < HelloResponse > CreateSession ( string clientId , CancellationToken cancellationToken = default ( CancellationToken ) )
120+ private async Task < HelloResponse > CreateSession ( string vpn , string clientId , UserAgentPurpose purpose , CancellationToken cancellationToken = default ( CancellationToken ) )
120121 {
121- var userAgent = new UserAgent { ClientId = clientId , Purpose = UserAgentPurpose . PUB } ;
122+ var userAgent = new UserAgent { ClientId = clientId , Vpn = vpn , Purpose = purpose } ;
122123 using ( var udpClient = new UdpClient ( ) )
123124 {
124125 var writeCtx = new WriteBufferContext ( ) ;
@@ -143,7 +144,22 @@ public interface IEventMeshClientPubSession
143144
144145 public interface IEventMeshClientSubSession
145146 {
147+ Task < SubscriptionResult > Subscribe ( string topicFilter , Action < CloudEvent > callback , CancellationToken cancellationToken ) ;
148+ }
149+
150+ public class SubscriptionResult
151+ {
152+ private readonly CancellationTokenSource _cancellationTokenSource ;
153+
154+ internal SubscriptionResult ( CancellationTokenSource cancellationTokenSource )
155+ {
156+ _cancellationTokenSource = cancellationTokenSource ;
157+ }
146158
159+ public void Close ( )
160+ {
161+ _cancellationTokenSource . Cancel ( ) ;
162+ }
147163 }
148164
149165 internal class EventMeshClientPubSession : IEventMeshClientPubSession
@@ -203,5 +219,69 @@ public EventMeshClientSubSession(HelloResponse session, IPAddress ipAddr, int po
203219 _ipAddr = ipAddr ;
204220 _port = port ;
205221 }
222+
223+ public async Task < SubscriptionResult > Subscribe ( string topicFilter , Action < CloudEvent > callback , CancellationToken cancellationToken )
224+ {
225+ var cancellationTokenSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
226+ var result = new SubscriptionResult ( cancellationTokenSource ) ;
227+ await Subscribe ( topicFilter , cancellationToken ) ;
228+ #pragma warning disable 4014
229+ Task . Run ( async ( ) => await Handle ( callback , cancellationTokenSource . Token ) ) ;
230+ #pragma warning restore 4014
231+ return result ;
232+ }
233+
234+ private async Task Subscribe ( string topicFilter , CancellationToken cancellationToken )
235+ {
236+ using ( var udpClient = new UdpClient ( ) )
237+ {
238+ var writeCtx = new WriteBufferContext ( ) ;
239+ var package = PackageRequestBuilder . Subscribe ( new List < SubscriptionItem >
240+ {
241+ new SubscriptionItem
242+ {
243+ Topic = topicFilter
244+ }
245+ } , _session . SessionId ) ;
246+ package . Serialize ( writeCtx ) ;
247+ var payload = writeCtx . Buffer . ToArray ( ) ;
248+ await udpClient . SendAsync ( payload , payload . Count ( ) , new IPEndPoint ( _ipAddr , _port ) ) . WithCancellation ( cancellationToken ) ;
249+ var resultPayload = await udpClient . ReceiveAsync ( ) . WithCancellation ( cancellationToken ) ;
250+ var readCtx = new ReadBufferContext ( resultPayload . Buffer ) ;
251+ var packageResult = Package . Deserialize ( readCtx ) ;
252+ EventMeshClient . EnsureSuccessStatus ( package , packageResult ) ;
253+ }
254+ }
255+
256+ private async Task Handle ( Action < CloudEvent > callback , CancellationToken cancellationToken )
257+ {
258+ try
259+ {
260+ while ( true )
261+ {
262+ cancellationToken . ThrowIfCancellationRequested ( ) ;
263+ using ( var udpClient = new UdpClient ( ) )
264+ {
265+ var writeCtx = new WriteBufferContext ( ) ;
266+ var package = PackageRequestBuilder . ReadNextMessage ( _session . SessionId ) ;
267+ package . Serialize ( writeCtx ) ;
268+ var payload = writeCtx . Buffer . ToArray ( ) ;
269+ await udpClient . SendAsync ( payload , payload . Count ( ) , new IPEndPoint ( _ipAddr , _port ) ) . WithCancellation ( cancellationToken ) ;
270+ var resultPayload = await udpClient . ReceiveAsync ( ) . WithCancellation ( cancellationToken ) ;
271+ var readCtx = new ReadBufferContext ( resultPayload . Buffer ) ;
272+ var packageResult = Package . Deserialize ( readCtx ) ;
273+ EventMeshClient . EnsureSuccessStatus ( package , packageResult ) ;
274+ var result = packageResult as ReadNextMessageResponse ;
275+ if ( result . ContainsMessage )
276+ {
277+ callback ( result . CloudEvt ) ;
278+ }
279+ }
280+
281+ Thread . Sleep ( 200 ) ;
282+ }
283+ }
284+ catch { }
285+ }
206286 }
207287}
0 commit comments