public int SendAction(ManagerAction action, ResponseHandler responseHandler) { if (action == null) throw new ArgumentException("Unable to send action: action is null."); if (mrSocket == null) throw new SystemException("Unable to send " + action.Action + " action: not connected."); // if the responseHandler is null the user is obviously not interested in the response, thats fine. string internalActionId = string.Empty; if (responseHandler != null) { internalActionId = createInternalActionId(); responseHandler.Hash = internalActionId.GetHashCode(); AddResponseHandler(responseHandler); } SendToAsterisk(action, internalActionId); return responseHandler != null ? responseHandler.Hash : 0; }
/// <summary> /// Reads line by line from the asterisk server, sets the protocol identifier as soon as it is /// received and dispatches the received events and responses via the associated dispatcher. /// </summary> /// <seealso cref="ManagerConnection.DispatchEvent(ManagerEvent)" /> /// <seealso cref="ManagerConnection.DispatchResponse(Response.ManagerResponse)" /> /// <seealso cref="ManagerConnection.setProtocolIdentifier(String)" /> internal void Run() { if (mrSocket == null) throw new SystemException("Unable to run: socket is null."); string line; while (true) { try { while (!die) { #region check line from * if (!is_logoff) { if (mrSocket != null && mrSocket.Initial) { Reinitialize(); } else if (disconnect) { disconnect = false; mrConnector.DispatchEvent(new DisconnectEvent(mrConnector)); } } if (lineQueue.Count == 0) { if (lastPacketTime.AddMilliseconds(mrConnector.PingInterval) < DateTime.Now && mrConnector.PingInterval > 0 && mrSocket != null && !wait4identiier && !is_logoff ) { if (pingHandler != null) { if (pingHandler.Response == null) { // If one PingInterval from Ping without Pong then send Disconnect event mrConnector.RemoveResponseHandler(pingHandler); mrConnector.DispatchEvent(new DisconnectEvent(mrConnector)); } pingHandler.Free(); pingHandler = null; } else { // Send PING to * try { pingHandler = new ResponseHandler(new Action.PingAction(), null); mrConnector.SendAction(pingHandler.Action, pingHandler); } catch { disconnect = true; mrSocket = null; } } lastPacketTime = DateTime.Now; } Thread.Sleep(50); if (mrConnector.TraceCallerThread && mrConnector.CallerThread != null && mrConnector.CallerThread.ThreadState == ThreadState.Stopped) { die = true; break; } continue; } #endregion lastPacketTime = DateTime.Now; lock (((ICollection)lineQueue).SyncRoot) line = lineQueue.Dequeue().Trim(); #if LOGGER logger.Debug(line); #endif #region processing Response: Follows if (processingCommandResult) { if (line == "--END COMMAND--") { Response.CommandResponse commandResponse = new Response.CommandResponse(); Helper.SetAttributes(commandResponse, packet); commandResponse.Result = commandList; processingCommandResult = false; packet.Clear(); mrConnector.DispatchResponse(commandResponse); continue; } else { string lineLower = line.ToLower(Helper.CultureInfo); if (lineLower.StartsWith("privilege: ") || lineLower.StartsWith("actionid: ") || lineLower.StartsWith("timestamp: ") || lineLower.StartsWith("server: ") ) Helper.AddKeyValue(packet, line); else commandList.Add(line); } continue; } #endregion #region collect key: value and ProtocolIdentifier if (!string.IsNullOrEmpty(line)) { if (wait4identiier && line.StartsWith("Asterisk Call Manager")) { wait4identiier = false; ConnectEvent connectEvent = new ConnectEvent(mrConnector); connectEvent.ProtocolIdentifier = line; mrConnector.DispatchEvent(connectEvent); continue; } if (line.Trim().ToLower(Helper.CultureInfo) == "response: follows") { // Switch to wait "--END COMMAND--" mode processingCommandResult = true; packet.Clear(); commandList.Clear(); Helper.AddKeyValue(packet, line); continue; } Helper.AddKeyValue(packet, line); continue; } #endregion #region process events and responses if (packet.ContainsKey("event")) mrConnector.DispatchEvent(packet); else if (packet.ContainsKey("response")) mrConnector.DispatchResponse(packet); #endregion packet.Clear(); } if(mrSocket != null) mrSocket.Close(); break; } #if LOGGER catch (Exception ex) { logger.Info("Exception : {0}", ex.Message); #else catch { #endif } if (die) break; #if LOGGER logger.Info("No die, any error - send disconnect."); #endif mrConnector.DispatchEvent(new DisconnectEvent(mrConnector)); } }
/// <summary> /// Send action ans with timeout (milliseconds) /// </summary> /// <param name="action">action to send</param> /// <param name="timeout">timeout in milliseconds</param> /// <returns></returns> public Response.ManagerResponse SendAction(ManagerAction action, int timeOut) { AutoResetEvent autoEvent = new AutoResetEvent(false); ResponseHandler handler = new ResponseHandler(action, autoEvent); int hash = SendAction(action, handler); bool result = autoEvent.WaitOne(timeOut <= 0 ? -1 : timeOut, true); RemoveResponseHandler(handler); if (result) return handler.Response; throw new TimeoutException("Timeout waiting for response to " + action.Action); }
/// <summary> /// Reads line by line from the asterisk server, sets the protocol identifier as soon as it is /// received and dispatches the received events and responses via the associated dispatcher. /// </summary> /// <seealso cref="ManagerConnection.DispatchEvent(ManagerEvent)" /> /// <seealso cref="ManagerConnection.DispatchResponse(Response.ManagerResponse)" /> /// <seealso cref="ManagerConnection.setProtocolIdentifier(String)" /> internal void Run() { if (mrSocket == null) { throw new SystemException("Unable to run: socket is null."); } string line; while (true) { try { while (!die) { #region check line from * if (!is_logoff) { if (mrSocket != null && mrSocket.Initial) { Reinitialize(); } else if (disconnect) { disconnect = false; mrConnector.DispatchEvent(new DisconnectEvent(mrConnector)); } } if (lineQueue.Count == 0) { if (mrConnector.PingInterval > 0 && mrSocket != null && !wait4identiier && !is_logoff && lastPacketTime.AddMilliseconds(mrConnector.PingInterval) < DateTime.Now ) { if (pingHandler != null) { // In 1.6.0 no Response from Ping if (pingHandler.Response == null) { // If one PingInterval from Ping without Pong then send Disconnect event mrConnector.DispatchEvent(new DisconnectEvent(mrConnector)); } pingHandler.Free(); mrConnector.RemoveResponseHandler(pingHandler); pingHandler = null; } else { // Send PING to * try { pingHandler = new ResponseHandler(new Action.PingAction(), null); mrConnector.SendAction(pingHandler.Action, pingHandler); } catch { disconnect = true; mrSocket = null; } } lastPacketTime = DateTime.Now; } Thread.Sleep(50); if (mrConnector.TraceCallerThread && mrConnector.CallerThread != null && mrConnector.CallerThread.ThreadState == ThreadState.Stopped) { die = true; break; } continue; } #endregion lastPacketTime = DateTime.Now; lock (((ICollection)lineQueue).SyncRoot) line = lineQueue.Dequeue().Trim(); #if LOGGER logger.Debug(line); #endif #region processing Response: Follows if (processingCommandResult) { if (line == "--END COMMAND--") { Response.CommandResponse commandResponse = new Response.CommandResponse(); Helper.SetAttributes(commandResponse, packet); commandResponse.Result = commandList; processingCommandResult = false; packet.Clear(); mrConnector.DispatchResponse(commandResponse); continue; } else { string lineLower = line.ToLower(Helper.CultureInfo); if (lineLower.StartsWith("privilege: ") || lineLower.StartsWith("actionid: ") || lineLower.StartsWith("timestamp: ") || lineLower.StartsWith("server: ") ) { Helper.AddKeyValue(packet, line); } else { commandList.Add(line); } } continue; } #endregion #region collect key: value and ProtocolIdentifier if (!string.IsNullOrEmpty(line)) { if (wait4identiier && line.StartsWith("Asterisk Call Manager")) { wait4identiier = false; ConnectEvent connectEvent = new ConnectEvent(mrConnector); connectEvent.ProtocolIdentifier = line; mrConnector.DispatchEvent(connectEvent); continue; } if (line.Trim().ToLower(Helper.CultureInfo) == "response: follows") { // Switch to wait "--END COMMAND--" mode processingCommandResult = true; packet.Clear(); commandList.Clear(); Helper.AddKeyValue(packet, line); continue; } Helper.AddKeyValue(packet, line); continue; } #endregion #region process events and responses if (packet.ContainsKey("event")) { mrConnector.DispatchEvent(packet); } else if (packet.ContainsKey("response")) { mrConnector.DispatchResponse(packet); } #endregion packet.Clear(); } if (mrSocket != null) { mrSocket.Close(); } break; } #if LOGGER catch (Exception ex) { logger.Info("Exception : {0}", ex.Message); #else catch { #endif } if (die) { break; } #if LOGGER logger.Info("No die, any error - send disconnect."); #endif mrConnector.DispatchEvent(new DisconnectEvent(mrConnector)); } }