From fcd5df08888bb8a5f2a77f6b8c41b9520b487531 Mon Sep 17 00:00:00 2001 From: "roger.castaldo@gmail.com" Date: Sun, 24 Mar 2013 19:50:24 +0000 Subject: [PATCH] added in a couple new message types to handle disconnect notices as well as authentication requests. added in code to handle the message content types more efficiently using switch case. --- FreeswitchConfigSockets.suo | Bin 34816 -> 38400 bytes Library/ASocket.cs | 198 +++++++++--------- .../Messages/AuthenticationRequestMessage.cs | 12 ++ Library/Messages/DisconnectNoticeMessage.cs | 27 +++ Library/Outbound/OutboundSocket.cs | 23 +- Library/SocketsLibrary.csproj | 6 +- 6 files changed, 164 insertions(+), 102 deletions(-) create mode 100644 Library/Messages/AuthenticationRequestMessage.cs create mode 100644 Library/Messages/DisconnectNoticeMessage.cs diff --git a/FreeswitchConfigSockets.suo b/FreeswitchConfigSockets.suo index b981a3b9a83a116d055e2203d5092c4f27a85593..fa88a4e1762d4671780a99eff9267f1335e6a361 100644 GIT binary patch delta 2988 zcmcJRdr(wW9LLYOT$Tl8c?kGiSc6d@HhC<#qUkOVLwU#!jE*xn!z!R60t4#u(&K0j@CKz+55Y{ zbI!fz{9b#NE=lQ;x@dT;Zc?q2h z%b;{wrr+e^P#y`r0Z?^~30gfVdYQHcms61|jT8fB1y{=NiV5YqO8JZs4(rn78X;WK zok}|kp%&DEwO}1s59+}N&;T}qEr8w&Ns8PGp$)VH1*kuVe5ISOW53+FF~~U-e(kfP zmgsTy>Ys)VNt!-^+M~8}g?^9n@a@zVUCd|Dw%R!~5dC>5lkm_O;5(%*4mW=U(d|h~ zxmip*;ELfoJCrA4)b`kqB|0Z(sIDnHxg?p?+f$>ZQVRwRph&aG=#>q6Rh5D8!)4l~&6k%-jY{a8l(VYk#Aywg^V_(#G_eBUL z{}qqm<*m$(-ofn1pM2zv1>KIk5&kIDWHWvjV=M8?-Gp!>3Ki3HPwK z_jrahYc+pwWDj_d(dP&_!ja%pW1}G=ARM$a^l-W!C(iJRY5oK^Hl7QQY+|icow%Fa zPwu3PY3*byw$QP%BD$oXO{a}+Phi+O;gKe+-2hLy{D`3Dq-Okpz?^3365O`{!I^;G@ne(If9Cc;+jTb?6Pq;WM_Zg{nvSIKwBxvnbP|nGMvC2ArI1n)&n@H#o=JT%mf#ODMWHBtvA15YmaKAd z&ye9oG6lM3bn=K9zIOVqvwf;B?z7sN14^A%Ah#h!7r-b@*wZGhYKTg*5c%+p$>)Ay_Nwqm~dC{1O6bF@YBgXhtGsYx0 zD}mMg|EMa|zI8UPe;kuL#U}Li$+o8a4qMUA8-lQ8=9mQJ>YJ0~`PM6!xh_4W8 zE|sabY&WHsG^iHO4-%J&=bxpU4@Hjq;ow|2na8P)>Vy2G<2diGc7%>ZmO8l7$Z6IS UU-QW--@HELzk6NOjvwW}0MbjV00000 delta 1088 zcmY+DUrbw79LLW&y=^Z+e*Ecy2!V{ki9! z{C?l_yY`2|z9=r5TsidPH8Vll!Pdzesu9(F=wKJqu1aQ1(6*|5WEd+(It$ z8GZ~mct@Jn@BEZllNATfm&x}UM}1df<=kma=pj0(g4k(QTCK|*A~J=UwncfXxty<< zuW`(u*^nDY`#H?hX$qc$(a@^*Tp?T@-pY1LLJn zRePM{RQ4^1)EnsQuEo{fr(xF3z#ci|F4c|+=S6fznlU$R$i&$gNAp4em33)ZI5F=+ zxX$L&rDkT@>gDZ0pAZ9mQarD7? z{17SRB89Np_z~>!7~cY)9gya+YK|7ixpLm-RQ2~VIhr9MlBP2j7kqzdIIOW=b=TM& zOKQPgqQQE38TqBW%)erCUHximK~LA`lA(&XY3Dn{y97=0K1`-*k`uU@4zDIv2Ps?H znS`tK;r+Xgm75dya9nS2V2%dlr3=-3B|pWT5!12axZ$Rmvz9rpl6-O8OP6x{Ke6Sh b?60EKl5BClbRl(c3DvVT7@7 _splitMessages; private List _processingMessages; - private bool _processing = false; private List _handlers; - private Queue _awaitingCommands; + protected Queue _awaitingCommands; private bool _exit = false; private IPAddress _ipAddress; private int _port; - private string _password; private string _currentCommandID; private delProcessEventMessage _eventProcessor; private Queue _awaitingCommandsEvents; @@ -206,7 +204,7 @@ protected string _IssueAPICommand(string command, bool api) return ""; } - protected ASocket(IPAddress ip, int port,string password) + protected ASocket(IPAddress ip, int port) { _textReceived = ""; _processingMessages = new List(); @@ -221,7 +219,6 @@ protected ASocket(IPAddress ip, int port,string password) _isConnected = false; _ipAddress = ip; _port = port; - _password = password; _awaitingCommands = new Queue(); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _mreMessageWaiting = new ManualResetEvent(false); @@ -243,11 +240,8 @@ private void BackgroundRun() try { _socket.Connect(_ipAddress, _port); - byte[] data = ASCIIEncoding.ASCII.GetBytes(string.Format(AUTH_COMMAND, _password) + MESSAGE_END_STRING); - _socket.Send(data, 0, data.Length, SocketFlags.None); _backgroundDataReader = new Thread(new ThreadStart(_SocketDataReaderStart)); _backgroundDataReader.Start(); - _isConnected = true; } catch (Exception e) { @@ -258,14 +252,6 @@ private void BackgroundRun() break; } } - if (!_exit) - { - lock (_awaitingCommands) - { - while (_awaitingCommands.Count > 0) - _sendCommand(_awaitingCommands.Dequeue()); - } - } } protected void _sendCommand(string commandString) @@ -289,7 +275,19 @@ protected void _sendCommand(byte[] commandBytes) } else { - _socket.Send(commandBytes, 0, commandBytes.Length, SocketFlags.None); + try + { + _socket.Send(commandBytes, 0, commandBytes.Length, SocketFlags.None); + } + catch (Exception e) + { + if (e is ObjectDisposedException) + { + _exit = true; + _isConnected = false; + } + throw e; + } } } @@ -430,106 +428,110 @@ private void _MessageProcessorStart() //fail safe for delayed header if (!pars.ContainsKey("Content-Type")) { - if (pars.ContainsKey("Event-Name")) - { - _processingMessages.Insert(0, origMsg); - origMsg = "Content-Type:text/event-plain\nContent-Length:" + origMsg.Length.ToString() + "\n"; - pars = ASocketMessage.ParseProperties(origMsg); - } - else - { - if (DisposeInvalidMessage != null) - DisposeInvalidMessage(origMsg); - break; - } + if (_disposeInvalidMesssage != null) + _disposeInvalidMesssage(origMsg); + break; } if (pars.ContainsKey("Content-Length")) { - if (_processingMessages.Count > 0) - { - subMsg = _processingMessages[0]; - _processingMessages.RemoveAt(0); - } - else + if (int.Parse(pars["Content-Length"]) > 0) { - _processingMessages.Insert(0, origMsg); - break; + if (_processingMessages.Count > 0) + { + subMsg = _processingMessages[0]; + _processingMessages.RemoveAt(0); + } + else + { + _processingMessages.Insert(0, origMsg); + break; + } } } - if (pars["Content-Type"] == "text/event-plain") + switch (pars["Content-Type"]) { - if (subMsg == "") - { - _processingMessages.Insert(0, origMsg); - break; - } - else - { - SocketEvent se; - se = new SocketEvent(subMsg); - if (se["Content-Length"] != null) + case "text/event-plain": + if (subMsg == "") { - if (_processingMessages.Count > 0) - { - se.Message = _processingMessages[0]; - _processingMessages.RemoveAt(0); - } - else - { - _processingMessages.Insert(0, origMsg); - _processingMessages.Insert(1, subMsg); - break; - } + _processingMessages.Insert(0, origMsg); + break; } - if (se.EventName == "BACKGROUND_JOB") + else { - lock (_commandThreads) + SocketEvent se; + se = new SocketEvent(subMsg); + if (se["Content-Length"] != null) + { + if (_processingMessages.Count > 0) + { + se.Message = _processingMessages[0]; + _processingMessages.RemoveAt(0); + } + else + { + _processingMessages.Insert(0, origMsg); + _processingMessages.Insert(1, subMsg); + break; + } + } + if (se.EventName == "BACKGROUND_JOB") { - if (_commandThreads.ContainsKey(se["Job-UUID"])) + lock (_commandThreads) { - lock (_awaitingCommandReturns) + if (_commandThreads.ContainsKey(se["Job-UUID"])) { - _awaitingCommandReturns.Add(se["Job-UUID"], se.Message.Trim('\n')); + lock (_awaitingCommandReturns) + { + _awaitingCommandReturns.Add(se["Job-UUID"], se.Message.Trim('\n')); + } + ManualResetEvent mre = _commandThreads[se["Job-UUID"]]; + _commandThreads.Remove(se["Job-UUID"]); + mre.Set(); } - ManualResetEvent mre = _commandThreads[se["Job-UUID"]]; - _commandThreads.Remove(se["Job-UUID"]); - mre.Set(); } } + msgs.Enqueue(se); } - msgs.Enqueue(se); - } - } - else if (pars["Content-Type"] == "command/reply") - { - CommandReplyMessage crm = new CommandReplyMessage(origMsg, subMsg); - msgs.Enqueue(crm); - if (crm["Job-UUID"] != null) - { - lock (_awaitingCommandsEvents) + break; + case "command/reply": + CommandReplyMessage crm = new CommandReplyMessage(origMsg, subMsg); + msgs.Enqueue(crm); + if (crm["Job-UUID"] != null) + { + lock (_awaitingCommandsEvents) + { + _currentCommandID = crm["Job-UUID"]; + _awaitingCommandsEvents.Dequeue().Set(); + } + } + break; + case "log/data": + SocketLogMessage lg; + lg = new SocketLogMessage(subMsg); + if (_processingMessages.Count > 0) { - _currentCommandID = crm["Job-UUID"]; - _awaitingCommandsEvents.Dequeue().Set(); + string eventMsg = _processingMessages[0]; + _processingMessages.RemoveAt(0); + lg.FullMessage = eventMsg; + msgs.Enqueue(lg); + } + else + { + _processingMessages.Insert(0, origMsg); + _processingMessages.Insert(1, subMsg); + break; } - } - } - else if (pars["Content-Type"] == "log/data") - { - SocketLogMessage lg; - lg = new SocketLogMessage(subMsg); - if (_processingMessages.Count > 0) - { - string eventMsg = _processingMessages[0]; - _processingMessages.RemoveAt(0); - lg.FullMessage = eventMsg; - msgs.Enqueue(lg); - } - else - { - _processingMessages.Insert(0, origMsg); - _processingMessages.Insert(1, subMsg); break; - } + case "text/disconnect-notice": + msgs.Enqueue(new DisconnectNoticeMessage(origMsg)); + break; + case "auth/request": + msgs.Enqueue(new AuthenticationRequestMessage(origMsg)); + break; + default: + if (_disposeInvalidMesssage != null) + _disposeInvalidMesssage(origMsg); + break; } } if (msgs.Count > 0) diff --git a/Library/Messages/AuthenticationRequestMessage.cs b/Library/Messages/AuthenticationRequestMessage.cs new file mode 100644 index 0000000..a9ef407 --- /dev/null +++ b/Library/Messages/AuthenticationRequestMessage.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Org.Reddragonit.FreeSwitchSockets.Messages +{ + public class AuthenticationRequestMessage : ASocketMessage + { + public AuthenticationRequestMessage(string message) + : base(message) { } + } +} diff --git a/Library/Messages/DisconnectNoticeMessage.cs b/Library/Messages/DisconnectNoticeMessage.cs new file mode 100644 index 0000000..73084a2 --- /dev/null +++ b/Library/Messages/DisconnectNoticeMessage.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Org.Reddragonit.FreeSwitchSockets.Messages +{ + public class DisconnectNoticeMessage : ASocketMessage + { + public DisconnectNoticeMessage(string message) + : base(message) { } + + public int LingerTime + { + get { return int.Parse(this["Linger-Time"]); } + } + + public string ChannelName + { + get { return this["Channel-Name"]; } + } + + public string SessionUUID + { + get { return this["Controlled-Session-UUID"]; } + } + } +} diff --git a/Library/Outbound/OutboundSocket.cs b/Library/Outbound/OutboundSocket.cs index c188992..e65c254 100644 --- a/Library/Outbound/OutboundSocket.cs +++ b/Library/Outbound/OutboundSocket.cs @@ -17,6 +17,7 @@ public class OutboundSocket : ASocket public const string DEFAULT_EVENT_SOCKET_LISTEN_IP = "127.0.0.1"; public const int DEFAULT_EVENT_SOCKET_LISTEN_PORT = 8021; public const string DEFAULT_EVENT_SOCKET_PASSWORD = "ClueCon"; + private const string AUTH_COMMAND = "auth {0}\n\n"; private struct sCommand { @@ -54,14 +55,16 @@ public sCommand(string command, bool api,MT19937 random) private delProcessEventMessage _eventDelegate; private delReloadXml _preReloadCall; private delReloadXml _postReloadCall; + private string _password; public OutboundSocket(IPAddress ip,int port,string password,delProcessEventMessage eventDelegate,delProcessLogMessage logDelegate,delReloadXml preReloadCall,delReloadXml postReloadCall) - : base(ip,port,password) + : base(ip,port) { _eventDelegate = eventDelegate; _logDelegate = logDelegate; _preReloadCall = preReloadCall; _postReloadCall = postReloadCall; + _password = password; } public string IssueCommand(string command) @@ -88,7 +91,23 @@ protected override void _processMessageQueue(Queue messages) while (messages.Count > 0) { ASocketMessage asm = messages.Dequeue(); - new Thread(new ParameterizedThreadStart(_processMessage)).Start(asm); + if (asm is AuthenticationRequestMessage) + { + socket.Send(ASCIIEncoding.ASCII.GetBytes(string.Format(AUTH_COMMAND, _password))); + IsConnected = true; + lock (_awaitingCommands) + { + if (!_exit) + { + while (_awaitingCommands.Count > 0) + { + byte[] commandBytes = _awaitingCommands.Dequeue(); + socket.Send(commandBytes, 0, commandBytes.Length, SocketFlags.None); + } + } + } + }else + new Thread(new ParameterizedThreadStart(_processMessage)).Start(asm); } } diff --git a/Library/SocketsLibrary.csproj b/Library/SocketsLibrary.csproj index 94264c8..03d91a0 100644 --- a/Library/SocketsLibrary.csproj +++ b/Library/SocketsLibrary.csproj @@ -3,12 +3,12 @@ Debug AnyCPU - 9.0.21022 + 9.0.30729 2.0 {959D2956-E058-470C-B415-851FC334A00C} Library Properties - Org.Reddragonit.FreeSwitch.Sockets + Org.Reddragonit.FreeSwitchSockets Socket v2.0 512 @@ -40,10 +40,12 @@ + +