44using System . Collections . Generic ;
55using Newtonsoft . Json . Linq ;
66using Microsoft . Extensions . Logging ;
7+ using PuppeteerSharp . Helpers ;
78
89namespace PuppeteerSharp
910{
@@ -33,30 +34,33 @@ namespace PuppeteerSharp
3334 /// });
3435 /// ]]></code>
3536 /// </summary>
36- public class CDPSession : IDisposable
37+ public class CDPSession : IConnection
3738 {
38- internal CDPSession ( Connection connection , string targetId , string sessionId )
39+ internal CDPSession ( IConnection connection , TargetType targetType , string sessionId , ILoggerFactory loggerFactory = null )
3940 {
41+ LoggerFactory = loggerFactory ?? new LoggerFactory ( ) ;
4042 Connection = connection ;
41- TargetId = targetId ;
43+ TargetType = targetType ;
4244 SessionId = sessionId ;
4345
4446 _callbacks = new Dictionary < int , MessageTask > ( ) ;
4547 _logger = Connection . LoggerFactory . CreateLogger < CDPSession > ( ) ;
48+ _sessions = new Dictionary < string , CDPSession > ( ) ;
4649 }
4750
4851 #region Private Members
4952 private int _lastId ;
5053 private readonly Dictionary < int , MessageTask > _callbacks ;
5154 private readonly ILogger _logger ;
55+ private readonly Dictionary < string , CDPSession > _sessions ;
5256 #endregion
5357
5458 #region Properties
5559 /// <summary>
56- /// Gets the target identifier .
60+ /// Gets the target type .
5761 /// </summary>
58- /// <value>The target identifier .</value>
59- public string TargetId { get ; }
62+ /// <value>The target type .</value>
63+ public TargetType TargetType { get ; }
6064 /// <summary>
6165 /// Gets the session identifier.
6266 /// </summary>
@@ -66,7 +70,7 @@ internal CDPSession(Connection connection, string targetId, string sessionId)
6670 /// Gets the connection.
6771 /// </summary>
6872 /// <value>The connection.</value>
69- public Connection Connection { get ; private set ; }
73+ internal IConnection Connection { get ; private set ; }
7074 /// <summary>
7175 /// Occurs when message received from Chromium.
7276 /// </summary>
@@ -80,6 +84,12 @@ internal CDPSession(Connection connection, string targetId, string sessionId)
8084 /// </summary>
8185 /// <value><c>true</c> if is closed; otherwise, <c>false</c>.</value>
8286 public bool IsClosed { get ; internal set ; }
87+
88+ /// <summary>
89+ /// Gets the logger factory.
90+ /// </summary>
91+ /// <value>The logger factory.</value>
92+ public ILoggerFactory LoggerFactory { get ; }
8393 #endregion
8494
8595 #region Public Methods
@@ -90,7 +100,13 @@ internal async Task<T> SendAsync<T>(string method, dynamic args = null)
90100 return JsonConvert . DeserializeObject < T > ( content ) ;
91101 }
92102
93- internal Task < dynamic > SendAsync ( string method , dynamic args = null )
103+ /// <summary>
104+ /// Sends a message to chromium.
105+ /// </summary>
106+ /// <returns>The async.</returns>
107+ /// <param name="method">Method to call.</param>
108+ /// <param name="args">Method arguments.</param>
109+ public Task < dynamic > SendAsync ( string method , dynamic args = null )
94110 {
95111 return SendAsync ( method , false , args ?? new { } ) ;
96112 }
@@ -99,9 +115,9 @@ internal async Task<dynamic> SendAsync(string method, bool rawContent, dynamic a
99115 {
100116 if ( Connection == null )
101117 {
102- throw new Exception ( $ "Protocol error ({ method } ): Session closed. Most likely the page has been closed.") ;
118+ throw new Exception ( $ "Protocol error ({ method } ): Session closed. Most likely the { TargetType } has been closed.") ;
103119 }
104- int id = ++ _lastId ;
120+ var id = ++ _lastId ;
105121 var message = JsonConvert . SerializeObject ( new Dictionary < string , object >
106122 {
107123 { "id" , id } ,
@@ -150,23 +166,6 @@ public Task DetachAsync()
150166
151167 #region Private Methods
152168
153- /// <summary>
154- /// Releases all resource used by the <see cref="CDPSession"/> object by sending a ""Target.closeTarget"
155- /// using the <see cref="Connection.SendAsync(string, dynamic)"/> method.
156- /// </summary>
157- /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="CDPSession"/>. The
158- /// <see cref="Dispose"/> method leaves the <see cref="CDPSession"/> in an unusable state.
159- /// After calling <see cref="Dispose"/>, you must release all references to the
160- /// <see cref="CDPSession"/> so the garbage collector can reclaim the memory that the
161- /// <see cref="CDPSession"/> was occupying.</remarks>
162- public void Dispose ( )
163- {
164- Connection . SendAsync ( "Target.closeTarget" , new Dictionary < string , object >
165- {
166- [ "targetId" ] = TargetId
167- } ) . GetAwaiter ( ) . GetResult ( ) ;
168- }
169-
170169 internal void OnMessage ( string message )
171170 {
172171 dynamic obj = JsonConvert . DeserializeObject ( message ) ;
@@ -197,15 +196,33 @@ internal void OnMessage(string message)
197196 }
198197 }
199198 }
200- else if ( obj . method == "Tracing.tracingComplete" )
201- {
202- TracingComplete ? . Invoke ( this , new TracingCompleteEventArgs
203- {
204- Stream = objAsJObject [ "params" ] . Value < string > ( "stream" )
205- } ) ;
206- }
207199 else
208200 {
201+ if ( obj . method == "Tracing.tracingComplete" )
202+ {
203+ TracingComplete ? . Invoke ( this , new TracingCompleteEventArgs
204+ {
205+ Stream = objAsJObject [ "params" ] . Value < string > ( "stream" )
206+ } ) ;
207+ }
208+ else if ( obj . method == "Target.receivedMessageFromTarget" )
209+ {
210+ var session = _sessions . GetValueOrDefault ( objAsJObject [ "params" ] [ "sessionId" ] . ToString ( ) ) ;
211+ if ( session != null )
212+ {
213+ session . OnMessage ( objAsJObject [ "params" ] [ "message" ] . ToString ( ) ) ;
214+ }
215+ }
216+ else if ( obj . method == "Target.detachedFromTarget" )
217+ {
218+ var session = _sessions . GetValueOrDefault ( objAsJObject [ "params" ] [ "sessionId" ] . ToString ( ) ) ;
219+ if ( ! ( session ? . IsClosed ?? true ) )
220+ {
221+ session . OnClosed ( ) ;
222+ _sessions . Remove ( objAsJObject [ "params" ] [ "sessionId" ] . ToString ( ) ) ;
223+ }
224+ }
225+
209226 MessageReceived ? . Invoke ( this , new MessageEventArgs
210227 {
211228 MessageID = obj . method ,
@@ -227,6 +244,12 @@ internal void OnClosed()
227244 Connection = null ;
228245 }
229246
247+ internal CDPSession CreateSession ( TargetType targetType , string sessionId )
248+ {
249+ var session = new CDPSession ( this , targetType , sessionId ) ;
250+ _sessions [ sessionId ] = session ;
251+ return session ;
252+ }
230253 #endregion
231254 }
232- }
255+ }
0 commit comments