protected void SendReply(ProcessState state, MemoryStream reply, int replyLength) { SocketError socketError; try { int replySize = replyLength + 4; if (state.messageId != 0) //if the client sent a message Id, we need to send it back { replySize += 2; } state.replyBuffer = bufferPool.GetItem(); if (state.replyBuffer.Item.Position > 0) { if (log.IsErrorEnabled) log.ErrorFormat("Buffer from pool had position {0}!. Resetting position and length.", state.replyBuffer.Item.Position.ToString("N0")); state.replyBuffer.Item.Seek(0, SeekOrigin.Begin); state.replyBuffer.Item.SetLength(0); } if (UseDefaultReplyHeader) { state.replyBuffer.Item.Write(BitConverter.GetBytes(GetNetworkOrdered(replySize, useNetworkOrder)), 0, 4); if (state.messageId != 0) { state.replyBuffer.Item.Write(BitConverter.GetBytes(GetNetworkOrdered(state.messageId, useNetworkOrder)), 0, 2); } state.replyBuffer.Item.Write(reply.GetBuffer(), 0, replyLength); } if (state.socket.Connected) { state.socket.BeginSend(state.replyBuffer.Item.GetBuffer(), 0, replySize, SocketFlags.None, out socketError, replyCallBack, state); if (socketError != SocketError.Success) { if (log.IsErrorEnabled) log.ErrorFormat("Error sending reply to {0}: {1}.", state.remoteEndpoint, socketError); if (!state.socket.Connected) { state.socket.Shutdown(SocketShutdown.Both); state.socket.Close(); } RemoveConnection(state.remoteEndpoint); } } else { if (log.IsErrorEnabled) log.ErrorFormat("Connection dropped before reply sent to {0}", state.remoteEndpoint); bufferPool.ReleaseItem(state.replyBuffer); state.replyBuffer = null; } } catch (SocketException ex) { if (state.replyBuffer != null) { bufferPool.ReleaseItem(state.replyBuffer); state.replyBuffer = null; } if (log.IsErrorEnabled) log.ErrorFormat("Socket Exception during SendReply to {0}: {1}. Removing connection.", state.remoteEndpoint, ex); try { if (state.socket.Connected) { state.socket.Shutdown(SocketShutdown.Both); state.socket.Close(); } RemoveConnection(state.remoteEndpoint); } catch (Exception exc) { if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception attempted to remove connection in SendReply exception cleanup: {0}", exc); } } catch (ObjectDisposedException) { if (state.replyBuffer != null) { bufferPool.ReleaseItem(state.replyBuffer); state.replyBuffer = null; } } catch (Exception ex) { if (state.replyBuffer != null) { bufferPool.ReleaseItem(state.replyBuffer); state.replyBuffer = null; } if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception during SendReply to {0}: {1}.", state.remoteEndpoint, ex); } }
private void SendReply(ProcessState state, MemoryStream replyStream) { int replyLength; if (replyStream == null) { replyStream = emptyReplyStream; replyLength = 4; } else { replyLength = (int)replyStream.Length; } SendReply(state, replyStream, replyLength); }
protected void ProcessCall(ProcessState state) { MemoryStream messageStream = null; MemoryStream replyStream = null; MessageState message = null; try { messageStream = state.message.Item; if (asyncMessageHandler != null) { message = new MessageState { CommandId = state.commandId, Message = messageStream, Length = state.messageLength, ClientIP = state.remoteEndpoint }; asyncMessageHandler.BeginHandleMessage(message, (asyncResult) => { try { MemoryStream reply = asyncMessageHandler.EndHandleMessage(asyncResult); CompleteProcessCall(state, reply); //not APM } catch (Exception exc) { if (log.IsErrorEnabled) log.Error(exc); } }); return; //very important } if (AsynMessageHandler != null) { replyStream = AsynMessageHandler.Invoke((int)state.commandId, messageStream, state.remoteEndpoint.Address); } else if (MessageHandler != null) { replyStream = MessageHandler.HandleMessage((int)state.commandId, messageStream, state.messageLength); } } catch (Exception ex) { try { string endPoint = state.socket.RemoteEndPoint.ToString(); if (log.IsErrorEnabled) log.ErrorFormat("Socket Server Exception handling message from {0}: {1}.", endPoint, ex); replyStream = null; } catch (ObjectDisposedException) { } } finally { if (message != null) { message.Message = null; message.Length = 0; } bufferPool.ReleaseItem(state.message); state.message = null; } CompleteProcessCall(state, replyStream); }
private void CompleteProcessCall(ProcessState state, MemoryStream replyStream) { if (countersInitialized) { avgHandlerTimeBase.Increment(); } if (state.sendReply) { SendReply(state, replyStream); } }
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; } }