protected internal bool connect() { bool result = false; bool startReader = false; lock (lockSocket) { if (mrSocket == null) { #if LOGGER logger.Info("Connecting to {0}:{1}", hostname, port); #endif try { mrSocket = new SocketConnection(hostname, port, socketEncoding); result = mrSocket.IsConnected; } #if LOGGER catch (Exception ex) { logger.Info("Connect - Exception : {0}", ex.Message); #else catch { #endif result = false; } if (result) { if (this.mrReader == null) { mrReader = new ManagerReader(this); mrReaderThread = new Util.ThreadClass(new ThreadStart(this.mrReader.Run), "ManagerReader-" + DateTime.Now.Second); mrReader.Socket = mrSocket; startReader = true; } else mrReader.Socket = mrSocket; mrReader.Reinitialize(); } else mrSocket = null; } } if (startReader) mrReaderThread.Start(); return IsConnected(); }
/// <summary> Closes the socket connection.</summary> private void disconnect(bool withDie) { lock (lockSocket) { if (withDie) { reconnectEnable = false; reconnected = false; enableEvents = true; } if (mrReader != null) { if (withDie) { mrReader.Die = true; mrReader = null; } else mrReader.Socket = null; } if (this.mrSocket != null) { mrSocket.Close(); mrSocket = null; } responseEventHandlers.Clear(); responseHandlers.Clear(); pingHandlers.Clear(); } }
/// <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)); } }