ClientReliableChannelBinder.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System;
  7. using System.Runtime;
  8. using System.ServiceModel;
  9. using System.ServiceModel.Security;
  10. using System.ServiceModel.Diagnostics;
  11. abstract class ClientReliableChannelBinder<TChannel> : ReliableChannelBinder<TChannel>,
  12. IClientReliableChannelBinder
  13. where TChannel : class, IChannel
  14. {
  15. ChannelParameterCollection channelParameters;
  16. IChannelFactory<TChannel> factory;
  17. EndpointAddress to;
  18. Uri via;
  19. protected ClientReliableChannelBinder(EndpointAddress to, Uri via, IChannelFactory<TChannel> factory,
  20. MaskingMode maskingMode, TolerateFaultsMode faultMode, ChannelParameterCollection channelParameters,
  21. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  22. : base(factory.CreateChannel(to, via), maskingMode, faultMode,
  23. defaultCloseTimeout, defaultSendTimeout)
  24. {
  25. if (channelParameters == null)
  26. {
  27. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelParameters");
  28. }
  29. this.to = to;
  30. this.via = via;
  31. this.factory = factory;
  32. this.channelParameters = channelParameters;
  33. }
  34. // The server side must get a message to determine where the channel should go, thus it is
  35. // pointless to create a channel for the sake of receiving on the client side. Also, since
  36. // the client side can create channels there receive may enter an infinite loop if open
  37. // persistently throws.
  38. protected override bool CanGetChannelForReceive
  39. {
  40. get
  41. {
  42. return false;
  43. }
  44. }
  45. public override bool CanSendAsynchronously
  46. {
  47. get
  48. {
  49. return true;
  50. }
  51. }
  52. public override ChannelParameterCollection ChannelParameters
  53. {
  54. get
  55. {
  56. return this.channelParameters;
  57. }
  58. }
  59. protected override bool MustCloseChannel
  60. {
  61. get
  62. {
  63. return true;
  64. }
  65. }
  66. protected override bool MustOpenChannel
  67. {
  68. get
  69. {
  70. return true;
  71. }
  72. }
  73. public Uri Via
  74. {
  75. get
  76. {
  77. return this.via;
  78. }
  79. }
  80. public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback,
  81. object state)
  82. {
  83. return this.BeginRequest(message, timeout, this.DefaultMaskingMode, callback, state);
  84. }
  85. public IAsyncResult BeginRequest(Message message, TimeSpan timeout, MaskingMode maskingMode,
  86. AsyncCallback callback, object state)
  87. {
  88. RequestAsyncResult result = new RequestAsyncResult(this, callback, state);
  89. result.Start(message, timeout, maskingMode);
  90. return result;
  91. }
  92. protected override IAsyncResult BeginTryGetChannel(TimeSpan timeout,
  93. AsyncCallback callback, object state)
  94. {
  95. CommunicationState currentState = this.State;
  96. TChannel channel;
  97. if ((currentState == CommunicationState.Created)
  98. || (currentState == CommunicationState.Opening)
  99. || (currentState == CommunicationState.Opened))
  100. {
  101. channel = this.factory.CreateChannel(this.to, this.via);
  102. }
  103. else
  104. {
  105. channel = null;
  106. }
  107. return new CompletedAsyncResult<TChannel>(channel, callback, state);
  108. }
  109. public static IClientReliableChannelBinder CreateBinder(EndpointAddress to, Uri via,
  110. IChannelFactory<TChannel> factory, MaskingMode maskingMode, TolerateFaultsMode faultMode,
  111. ChannelParameterCollection channelParameters,
  112. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  113. {
  114. Type type = typeof(TChannel);
  115. if (type == typeof(IDuplexChannel))
  116. {
  117. return new DuplexClientReliableChannelBinder(to, via, (IChannelFactory<IDuplexChannel>)(object)factory, maskingMode,
  118. channelParameters, defaultCloseTimeout, defaultSendTimeout);
  119. }
  120. else if (type == typeof(IDuplexSessionChannel))
  121. {
  122. return new DuplexSessionClientReliableChannelBinder(to, via, (IChannelFactory<IDuplexSessionChannel>)(object)factory, maskingMode,
  123. faultMode, channelParameters, defaultCloseTimeout, defaultSendTimeout);
  124. }
  125. else if (type == typeof(IRequestChannel))
  126. {
  127. return new RequestClientReliableChannelBinder(to, via, (IChannelFactory<IRequestChannel>)(object)factory, maskingMode,
  128. channelParameters, defaultCloseTimeout, defaultSendTimeout);
  129. }
  130. else if (type == typeof(IRequestSessionChannel))
  131. {
  132. return new RequestSessionClientReliableChannelBinder(to, via, (IChannelFactory<IRequestSessionChannel>)(object)factory, maskingMode,
  133. faultMode, channelParameters, defaultCloseTimeout, defaultSendTimeout);
  134. }
  135. else
  136. {
  137. throw Fx.AssertAndThrow("ClientReliableChannelBinder supports creation of IDuplexChannel, IDuplexSessionChannel, IRequestChannel, and IRequestSessionChannel only.");
  138. }
  139. }
  140. public Message EndRequest(IAsyncResult result)
  141. {
  142. return RequestAsyncResult.End(result);
  143. }
  144. protected override bool EndTryGetChannel(IAsyncResult result)
  145. {
  146. TChannel channel = CompletedAsyncResult<TChannel>.End(result);
  147. if (channel != null && !this.Synchronizer.SetChannel(channel))
  148. {
  149. channel.Abort();
  150. }
  151. return true;
  152. }
  153. public bool EnsureChannelForRequest()
  154. {
  155. return this.Synchronizer.EnsureChannel();
  156. }
  157. protected override void OnAbort()
  158. {
  159. }
  160. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback,
  161. object state)
  162. {
  163. return new CompletedAsyncResult(callback, state);
  164. }
  165. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback,
  166. object state)
  167. {
  168. return new CompletedAsyncResult(callback, state);
  169. }
  170. protected virtual IAsyncResult OnBeginRequest(TChannel channel, Message message,
  171. TimeSpan timeout, MaskingMode maskingMode, AsyncCallback callback, object state)
  172. {
  173. throw Fx.AssertAndThrow("The derived class does not support the OnBeginRequest operation.");
  174. }
  175. protected override void OnClose(TimeSpan timeout)
  176. {
  177. }
  178. protected override void OnEndClose(IAsyncResult result)
  179. {
  180. CompletedAsyncResult.End(result);
  181. }
  182. protected override void OnEndOpen(IAsyncResult result)
  183. {
  184. CompletedAsyncResult.End(result);
  185. }
  186. protected virtual Message OnEndRequest(TChannel channel, MaskingMode maskingMode,
  187. IAsyncResult result)
  188. {
  189. throw Fx.AssertAndThrow("The derived class does not support the OnEndRequest operation.");
  190. }
  191. protected override void OnOpen(TimeSpan timeout)
  192. {
  193. }
  194. protected virtual Message OnRequest(TChannel channel, Message message, TimeSpan timeout,
  195. MaskingMode maskingMode)
  196. {
  197. throw Fx.AssertAndThrow("The derived class does not support the OnRequest operation.");
  198. }
  199. public Message Request(Message message, TimeSpan timeout)
  200. {
  201. return this.Request(message, timeout, this.DefaultMaskingMode);
  202. }
  203. public Message Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
  204. {
  205. if (!this.ValidateOutputOperation(message, timeout, maskingMode))
  206. {
  207. return null;
  208. }
  209. bool autoAborted = false;
  210. try
  211. {
  212. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  213. TChannel channel;
  214. if (!this.Synchronizer.TryGetChannelForOutput(timeoutHelper.RemainingTime(), maskingMode,
  215. out channel))
  216. {
  217. if (!ReliableChannelBinderHelper.MaskHandled(maskingMode))
  218. {
  219. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
  220. new TimeoutException(SR.GetString(SR.TimeoutOnRequest, timeout)));
  221. }
  222. return null;
  223. }
  224. if (channel == null)
  225. {
  226. return null;
  227. }
  228. try
  229. {
  230. return this.OnRequest(channel, message, timeoutHelper.RemainingTime(),
  231. maskingMode);
  232. }
  233. finally
  234. {
  235. autoAborted = this.Synchronizer.Aborting;
  236. this.Synchronizer.ReturnChannel();
  237. }
  238. }
  239. catch (Exception e)
  240. {
  241. if (Fx.IsFatal(e))
  242. throw;
  243. if (!this.HandleException(e, maskingMode, autoAborted))
  244. {
  245. throw;
  246. }
  247. else
  248. {
  249. return null;
  250. }
  251. }
  252. }
  253. protected override bool TryGetChannel(TimeSpan timeout)
  254. {
  255. CommunicationState currentState = this.State;
  256. TChannel channel = null;
  257. if ((currentState == CommunicationState.Created)
  258. || (currentState == CommunicationState.Opening)
  259. || (currentState == CommunicationState.Opened))
  260. {
  261. channel = this.factory.CreateChannel(this.to, this.via);
  262. if (!this.Synchronizer.SetChannel(channel))
  263. {
  264. channel.Abort();
  265. }
  266. }
  267. else
  268. {
  269. channel = null;
  270. }
  271. return true;
  272. }
  273. abstract class DuplexClientReliableChannelBinder<TDuplexChannel>
  274. : ClientReliableChannelBinder<TDuplexChannel>
  275. where TDuplexChannel : class, IDuplexChannel
  276. {
  277. public DuplexClientReliableChannelBinder(EndpointAddress to, Uri via,
  278. IChannelFactory<TDuplexChannel> factory, MaskingMode maskingMode, TolerateFaultsMode faultMode,
  279. ChannelParameterCollection channelParameters,
  280. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  281. : base(to, via, factory, maskingMode, faultMode, channelParameters, defaultCloseTimeout,
  282. defaultSendTimeout)
  283. {
  284. }
  285. public override EndpointAddress LocalAddress
  286. {
  287. get
  288. {
  289. IDuplexChannel channel = this.Synchronizer.CurrentChannel;
  290. if (channel == null)
  291. return null;
  292. else
  293. return channel.LocalAddress;
  294. }
  295. }
  296. public override EndpointAddress RemoteAddress
  297. {
  298. get
  299. {
  300. IDuplexChannel channel = this.Synchronizer.CurrentChannel;
  301. if (channel == null)
  302. return null;
  303. else
  304. return channel.RemoteAddress;
  305. }
  306. }
  307. protected override IAsyncResult OnBeginSend(TDuplexChannel channel, Message message,
  308. TimeSpan timeout, AsyncCallback callback, object state)
  309. {
  310. return channel.BeginSend(message, timeout, callback, state);
  311. }
  312. protected override IAsyncResult OnBeginTryReceive(TDuplexChannel channel,
  313. TimeSpan timeout, AsyncCallback callback, object state)
  314. {
  315. return channel.BeginTryReceive(timeout, callback, state);
  316. }
  317. protected override void OnEndSend(TDuplexChannel channel, IAsyncResult result)
  318. {
  319. channel.EndSend(result);
  320. }
  321. protected override bool OnEndTryReceive(TDuplexChannel channel, IAsyncResult result,
  322. out RequestContext requestContext)
  323. {
  324. Message message;
  325. bool success = channel.EndTryReceive(result, out message);
  326. if (success && message == null)
  327. {
  328. this.OnReadNullMessage();
  329. }
  330. requestContext = this.WrapMessage(message);
  331. return success;
  332. }
  333. protected virtual void OnReadNullMessage()
  334. {
  335. }
  336. protected override void OnSend(TDuplexChannel channel, Message message,
  337. TimeSpan timeout)
  338. {
  339. channel.Send(message, timeout);
  340. }
  341. protected override bool OnTryReceive(TDuplexChannel channel, TimeSpan timeout,
  342. out RequestContext requestContext)
  343. {
  344. Message message;
  345. bool success = channel.TryReceive(timeout, out message);
  346. if (success && message == null)
  347. {
  348. this.OnReadNullMessage();
  349. }
  350. requestContext = this.WrapMessage(message);
  351. return success;
  352. }
  353. }
  354. sealed class DuplexClientReliableChannelBinder
  355. : DuplexClientReliableChannelBinder<IDuplexChannel>
  356. {
  357. public DuplexClientReliableChannelBinder(EndpointAddress to, Uri via,
  358. IChannelFactory<IDuplexChannel> factory, MaskingMode maskingMode,
  359. ChannelParameterCollection channelParameters,
  360. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  361. : base(to, via, factory, maskingMode, TolerateFaultsMode.Never, channelParameters,
  362. defaultCloseTimeout, defaultSendTimeout)
  363. {
  364. }
  365. public override bool HasSession
  366. {
  367. get
  368. {
  369. return false;
  370. }
  371. }
  372. public override ISession GetInnerSession()
  373. {
  374. return null;
  375. }
  376. protected override bool HasSecuritySession(IDuplexChannel channel)
  377. {
  378. return false;
  379. }
  380. }
  381. sealed class DuplexSessionClientReliableChannelBinder
  382. : DuplexClientReliableChannelBinder<IDuplexSessionChannel>
  383. {
  384. public DuplexSessionClientReliableChannelBinder(EndpointAddress to, Uri via,
  385. IChannelFactory<IDuplexSessionChannel> factory, MaskingMode maskingMode, TolerateFaultsMode faultMode,
  386. ChannelParameterCollection channelParameters,
  387. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  388. : base(to, via, factory, maskingMode, faultMode, channelParameters, defaultCloseTimeout,
  389. defaultSendTimeout)
  390. {
  391. }
  392. public override bool HasSession
  393. {
  394. get
  395. {
  396. return true;
  397. }
  398. }
  399. public override ISession GetInnerSession()
  400. {
  401. return this.Synchronizer.CurrentChannel.Session;
  402. }
  403. protected override IAsyncResult BeginCloseChannel(IDuplexSessionChannel channel,
  404. TimeSpan timeout, AsyncCallback callback, object state)
  405. {
  406. return ReliableChannelBinderHelper.BeginCloseDuplexSessionChannel(this, channel,
  407. timeout, callback, state);
  408. }
  409. protected override void CloseChannel(IDuplexSessionChannel channel, TimeSpan timeout)
  410. {
  411. ReliableChannelBinderHelper.CloseDuplexSessionChannel(this, channel, timeout);
  412. }
  413. protected override void EndCloseChannel(IDuplexSessionChannel channel,
  414. IAsyncResult result)
  415. {
  416. ReliableChannelBinderHelper.EndCloseDuplexSessionChannel(channel, result);
  417. }
  418. protected override bool HasSecuritySession(IDuplexSessionChannel channel)
  419. {
  420. return channel.Session is ISecuritySession;
  421. }
  422. protected override void OnReadNullMessage()
  423. {
  424. this.Synchronizer.OnReadEof();
  425. }
  426. }
  427. abstract class RequestClientReliableChannelBinder<TRequestChannel>
  428. : ClientReliableChannelBinder<TRequestChannel>
  429. where TRequestChannel : class, IRequestChannel
  430. {
  431. InputQueue<Message> inputMessages;
  432. public RequestClientReliableChannelBinder(EndpointAddress to, Uri via,
  433. IChannelFactory<TRequestChannel> factory, MaskingMode maskingMode, TolerateFaultsMode faultMode,
  434. ChannelParameterCollection channelParameters,
  435. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  436. : base(to, via, factory, maskingMode, faultMode, channelParameters, defaultCloseTimeout,
  437. defaultSendTimeout)
  438. {
  439. }
  440. public override IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback,
  441. object state)
  442. {
  443. return this.GetInputMessages().BeginDequeue(timeout, callback, state);
  444. }
  445. public override bool EndTryReceive(IAsyncResult result,
  446. out RequestContext requestContext)
  447. {
  448. Message message;
  449. bool success = this.GetInputMessages().EndDequeue(result, out message);
  450. requestContext = this.WrapMessage(message);
  451. return success;
  452. }
  453. protected void EnqueueMessageIfNotNull(Message message)
  454. {
  455. if (message != null)
  456. {
  457. this.GetInputMessages().EnqueueAndDispatch(message);
  458. }
  459. }
  460. InputQueue<Message> GetInputMessages()
  461. {
  462. lock (this.ThisLock)
  463. {
  464. if (this.State == CommunicationState.Created)
  465. {
  466. throw Fx.AssertAndThrow("The method GetInputMessages() cannot be called when the binder is in the Created state.");
  467. }
  468. if (this.State == CommunicationState.Opening)
  469. {
  470. throw Fx.AssertAndThrow("The method GetInputMessages() cannot be called when the binder is in the Opening state.");
  471. }
  472. if (this.inputMessages == null)
  473. {
  474. this.inputMessages = TraceUtility.CreateInputQueue<Message>();
  475. }
  476. }
  477. return this.inputMessages;
  478. }
  479. public override EndpointAddress LocalAddress
  480. {
  481. get
  482. {
  483. return EndpointAddress.AnonymousAddress;
  484. }
  485. }
  486. public override EndpointAddress RemoteAddress
  487. {
  488. get
  489. {
  490. IRequestChannel channel = this.Synchronizer.CurrentChannel;
  491. if (channel == null)
  492. return null;
  493. else
  494. return channel.RemoteAddress;
  495. }
  496. }
  497. protected override IAsyncResult OnBeginRequest(TRequestChannel channel,
  498. Message message, TimeSpan timeout, MaskingMode maskingMode,
  499. AsyncCallback callback, object state)
  500. {
  501. return channel.BeginRequest(message, timeout, callback, state);
  502. }
  503. protected override IAsyncResult OnBeginSend(TRequestChannel channel, Message message,
  504. TimeSpan timeout, AsyncCallback callback, object state)
  505. {
  506. return channel.BeginRequest(message, timeout, callback, state);
  507. }
  508. protected override Message OnEndRequest(TRequestChannel channel,
  509. MaskingMode maskingMode, IAsyncResult result)
  510. {
  511. return channel.EndRequest(result);
  512. }
  513. protected override void OnEndSend(TRequestChannel channel, IAsyncResult result)
  514. {
  515. Message message = channel.EndRequest(result);
  516. this.EnqueueMessageIfNotNull(message);
  517. }
  518. protected override Message OnRequest(TRequestChannel channel, Message message,
  519. TimeSpan timeout, MaskingMode maskingMode)
  520. {
  521. return channel.Request(message, timeout);
  522. }
  523. protected override void OnSend(TRequestChannel channel, Message message,
  524. TimeSpan timeout)
  525. {
  526. message = channel.Request(message, timeout);
  527. this.EnqueueMessageIfNotNull(message);
  528. }
  529. protected override void OnShutdown()
  530. {
  531. if (this.inputMessages != null)
  532. {
  533. this.inputMessages.Close();
  534. }
  535. }
  536. public override bool TryReceive(TimeSpan timeout, out RequestContext requestContext)
  537. {
  538. Message message;
  539. bool success = this.GetInputMessages().Dequeue(timeout, out message);
  540. requestContext = this.WrapMessage(message);
  541. return success;
  542. }
  543. }
  544. sealed class RequestAsyncResult
  545. : ReliableChannelBinder<TChannel>.OutputAsyncResult<ClientReliableChannelBinder<TChannel>>
  546. {
  547. Message reply;
  548. public RequestAsyncResult(ClientReliableChannelBinder<TChannel> binder,
  549. AsyncCallback callback, object state)
  550. : base(binder, callback, state)
  551. {
  552. }
  553. protected override IAsyncResult BeginOutput(
  554. ClientReliableChannelBinder<TChannel> binder, TChannel channel, Message message,
  555. TimeSpan timeout, MaskingMode maskingMode, AsyncCallback callback, object state)
  556. {
  557. return binder.OnBeginRequest(channel, message, timeout, maskingMode, callback,
  558. state);
  559. }
  560. public static Message End(IAsyncResult result)
  561. {
  562. RequestAsyncResult requestResult = AsyncResult.End<RequestAsyncResult>(result);
  563. return requestResult.reply;
  564. }
  565. protected override void EndOutput(ClientReliableChannelBinder<TChannel> binder,
  566. TChannel channel, MaskingMode maskingMode, IAsyncResult result)
  567. {
  568. this.reply = binder.OnEndRequest(channel, maskingMode, result);
  569. }
  570. protected override string GetTimeoutString(TimeSpan timeout)
  571. {
  572. return SR.GetString(SR.TimeoutOnRequest, timeout);
  573. }
  574. }
  575. sealed class RequestClientReliableChannelBinder
  576. : RequestClientReliableChannelBinder<IRequestChannel>
  577. {
  578. public RequestClientReliableChannelBinder(EndpointAddress to, Uri via,
  579. IChannelFactory<IRequestChannel> factory, MaskingMode maskingMode,
  580. ChannelParameterCollection channelParameters,
  581. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  582. : base(to, via, factory, maskingMode, TolerateFaultsMode.Never, channelParameters,
  583. defaultCloseTimeout, defaultSendTimeout)
  584. {
  585. }
  586. public override bool HasSession
  587. {
  588. get
  589. {
  590. return false;
  591. }
  592. }
  593. public override ISession GetInnerSession()
  594. {
  595. return null;
  596. }
  597. protected override bool HasSecuritySession(IRequestChannel channel)
  598. {
  599. return false;
  600. }
  601. }
  602. sealed class RequestSessionClientReliableChannelBinder
  603. : RequestClientReliableChannelBinder<IRequestSessionChannel>
  604. {
  605. public RequestSessionClientReliableChannelBinder(EndpointAddress to, Uri via,
  606. IChannelFactory<IRequestSessionChannel> factory, MaskingMode maskingMode, TolerateFaultsMode faultMode,
  607. ChannelParameterCollection channelParameters,
  608. TimeSpan defaultCloseTimeout, TimeSpan defaultSendTimeout)
  609. : base(to, via, factory, maskingMode, faultMode, channelParameters, defaultCloseTimeout,
  610. defaultSendTimeout)
  611. {
  612. }
  613. public override bool HasSession
  614. {
  615. get
  616. {
  617. return true;
  618. }
  619. }
  620. public override ISession GetInnerSession()
  621. {
  622. return this.Synchronizer.CurrentChannel.Session;
  623. }
  624. protected override bool HasSecuritySession(IRequestSessionChannel channel)
  625. {
  626. return channel.Session is ISecuritySession;
  627. }
  628. }
  629. }
  630. }