public void Add(ConnectionState connection) { connectionsLock.Write(delegate { connections.Add(connection.remoteEndPoint, connection); IncrementCount(); }); }
public bool Remove(ConnectionState connection) { bool removed = false; connectionsLock.Write(delegate { removed = connections.Remove(connection.remoteEndPoint); if (removed) { DecrementCount(); } }); return removed; }
public void Purge() { ConnectionState[] values = null; connectionsLock.ReadUpgradable(delegate { values = new ConnectionState[connections.Count]; connections.Values.CopyTo(values, 0); connectionsLock.Write(delegate { connections.Clear(); ZeroCount(); }); }); foreach (var state in values) { try { Close(state); } catch (Exception ex) { if (SocketServer.log.IsErrorEnabled) SocketServer.log.ErrorFormat("Exception closing socket during shutdown: {0}",ex.ToString()); } } }
/// <summary> /// Closes out any connections that don't satisfy a supplied callback. /// </summary> /// <param name="connectionWhitelist"><see cref="ConnectionWhitelist"/> /// callback that takes the remote <see cref="IPEndPoint"/> and /// returns a <see cref="Boolean"/> specifying whether to retain /// the connection.</param> /// <remarks>If the callback returns <see langword="true"/> then /// the connection is retained; otherwise it is closed.</remarks> public void PurgeNotWhitelisted(ConnectionWhitelist connectionWhitelist) { var purgedStates = new List<ConnectionState>(); connectionsLock.ReadUpgradable(delegate { var count = connections.Count; var keys = new IPEndPoint[count]; connections.Keys.CopyTo(keys, 0); var values = new ConnectionState[count]; connections.Values.CopyTo(values, 0); for(var idx = count - 1; idx >= 0; --idx) { var key = keys[idx]; if (!connectionWhitelist(key)) { var value = values[idx]; connectionsLock.Write(delegate { connections.Remove(key); DecrementCount(); }); purgedStates.Add(value); } } }); foreach(var state in purgedStates) { try { Close(state); } catch (Exception ex) { if (SocketServer.log.IsErrorEnabled) SocketServer.log.ErrorFormat("Exception doing whitelist check of sockets for closing: {0}",ex.ToString()); } } }
private static void Close(ConnectionState state) { lock(state) { var socket = state.WorkSocket; if (socket != null) { state.WorkSocket = null; try { if (socket.Connected) { socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); socket.Shutdown(SocketShutdown.Both); socket.Close(); } } catch (ObjectDisposedException) { } // ignore for already closed outside this code } } }
private void ResetConnectionStateMessageBuffer(ConnectionState state) { if (state.messageSize > maximumMessageSize && !discardTooBigMessages) { state.messageBuffer.Dispose(); state.messageBuffer = new MemoryStream(initialMessageSize); } else { state.messageBuffer.Seek(0, SeekOrigin.Begin); state.messageBuffer.SetLength(0); } state.messagePosition = 0; state.messageSize = -1; }
private void ResetConnectionState(ConnectionState state) { state.WorkSocket = null; state.ReplySocket = null; state.remoteEndPoint = null; ResetConnectionStateMessageBuffer(state); }
protected void RemoveConnection(ConnectionState state) { connections.Remove(state); }
protected void HandleCompleteConnectionState(ConnectionState state) { bool sendReply = false; byte[] buff = state.messageBuffer.GetBuffer(); short commandId = 0; short messageId; try { if (useNetworkOrder) { messageId = GetHostOrdered(BitConverter.ToInt16(buff, 6), true); commandId = GetHostOrdered(BitConverter.ToInt16(buff, 8), true); } else { commandId = BitConverter.ToInt16(buff, 6); messageId = BitConverter.ToInt16(buff, 8); } sendReply = BitConverter.ToBoolean(buff, 10); if (countersInitialized) { if (sendReply) syncPerSecCounter.Increment(); else onewayPerSecCounter.Increment(); } } catch (Exception e) { if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception extracting message info from {0}: {1} . Resetting connection state.", state.remoteEndPoint, e); ResetConnectionStateMessageBuffer(state); return; } if (!CheckForMessageTerminator(buff, state.messageSize)) { if (log.IsErrorEnabled) log.ErrorFormat("Message without end terminator found from {0}. Resetting connection state.", state.remoteEndPoint); ResetConnectionStateMessageBuffer(state); return; } try { #region if replychannel if (commandId == SocketServer.ReplyChannelCreationCommandId) { try { byte[] justAddress = new byte[4]; Array.Copy(buff, 11, justAddress, 0, 4); IPAddress sendChannelAddress = new IPAddress(justAddress); IPEndPoint sendChannelEndPoint = new IPEndPoint(sendChannelAddress, BitConverter.ToInt32(buff, 15)); connections[sendChannelEndPoint].ReplySocket = state.WorkSocket; SendReplyChannelConfirmation(state.WorkSocket, true); } catch (Exception ex) { if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception creating reply socket for {0}: {1}", state.remoteEndPoint, ex); SendReplyChannelConfirmation(state.WorkSocket, false); } } #endregion else { ResourcePoolItem<MemoryStream> messageBuffer = bufferPool.GetItem(); ProcessState processState = null; try { messageBuffer.Item.Write(buff, 11, state.messageSize - 13); messageBuffer.Item.Seek(0, SeekOrigin.Begin); processState = new ProcessState(state.ReplySocket, commandId, messageId, sendReply, messageBuffer, state.messageSize - 13); if (sendReply) { SyncMessagePort.Post(processState); } else { OnewayMessagePort.Post(processState); } } catch (Exception ex) { if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception enqueueing message work item for {0}: {1}. Releasing buffer.", state.remoteEndPoint, ex); bufferPool.ReleaseItem(messageBuffer); } } } catch (Exception ex) { if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception while handling message for {0}: {1}. Resetting message state.", state.remoteEndPoint, ex); ResetConnectionStateMessageBuffer(state); return; } }