/// <summary> /// Initializes a new instance of the <see cref="ServerRecordHandlerBase{TRecord}" /> class. /// </summary> /// <param name="conn">The value for the <see cref="ServerRecordHandlerBase{TRecord}.ClientConnection" /> property.</param> /// <param name="record">The value for the <see cref="RecordHandlerBase{TRecord}.Record" /> property.</param> /// <param name="sync">The value for the <see cref="NotifiableBase.SyncRoot" /> property.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="record" /> is <see langword="null" />. /// </exception> /// <exception cref="NullReferenceException"> /// <paramref name="conn" /> is <see langword="null" />. /// </exception> protected ServerRecordHandlerBase(ConnectionWithClient conn, TRecord record, object sync = null) : base(appContext: conn.Host.Application, record: record, sync: sync) { this.ClientConnection = conn; }
/// <summary> /// Starts a new connection with a client. /// </summary> /// <param name="connection">The connection.</param> /// <returns> /// Operation was successful or not. /// <see langword="null" /> indicates that <paramref name="connection" /> is <see langword="null" />. /// </returns> protected virtual bool?StartCommunicationWithClient(ConnectionWithClient connection) { if (connection == null) { return(null); } try { Task.Factory .StartNew((state) => { var c = (ConnectionWithClient)state; try { using (c) { c.Host.RaiseEventHandler(this.Connected, new ClientConnectionEventArgs(c)); c.Start(); } } catch (ObjectDisposedException) { // ignore } catch (Exception ex) { c.Host.RaiseError(ex); } }, state: connection); return(true); } catch (Exception ex) { this.RaiseError(ex); return(false); } }
/// <summary> /// The async callback for <see cref="ServerHost.BeginAcceptingTcpClient(TcpListener, bool)" /> method. /// </summary> /// <param name="ar">The async result.</param> protected void EndAcceptingTcpClient(IAsyncResult ar) { var waitForNext = true; ConnectionWithClient clientConn = null; TcpListener listener = null; RemoteConnection remoteConn = null; Action disposeConnections = () => { if (clientConn != null) { try { clientConn.Dispose(); } catch (ObjectDisposedException) { // ignore } catch (Exception ex2) { this.RaiseError(ex2); } } else if (remoteConn != null) { try { remoteConn.Dispose(); } catch (ObjectDisposedException) { // ignore } catch (Exception ex2) { this.RaiseError(ex2); } } }; try { listener = ar.AsyncState as TcpListener; if (listener == null) { return; } var client = listener.EndAcceptTcpClient(ar); remoteConn = new RemoteConnection(this.Application, client.Client, true); clientConn = new ConnectionWithClient(this, remoteConn); clientConn.Closed += this.ConnectionWithClient_Closed; clientConn.Disposed += this.ConnectionWithClient_Disposed; this.InvokeForConnections((list, state) => list.Add(state.NewConnection), new { NewConnection = clientConn, }); if (this.StartCommunicationWithClient(clientConn).IsFalse()) { disposeConnections(); } } catch (ObjectDisposedException) { waitForNext = false; } catch (Exception ex) { disposeConnections(); this.RaiseError(ex); } finally { if (waitForNext) { this.BeginAcceptingTcpClient(listener); } } }