/// <summary> /// Exchange messages with Outlook. /// </summary> private void ChatWithOutlook() { Debug.Assert(m_msgQueue.Count == 0); Debug.Assert(m_chattingFlag); try { AnpTransport transport = new AnpTransport(m_outlookSock); while (true) { if (!transport.isReceiving) transport.beginRecv(); if (!transport.isSending && m_msgQueue.Count != 0) transport.sendMsg(m_msgQueue.Dequeue()); SelectSockets select = new SelectSockets(); select.AddRead(m_outlookSock); if (transport.isSending) select.AddWrite(m_outlookSock); Block(select); transport.doXfer(); if (transport.doneReceiving) { OutlookUiThreadMsg msg = new OutlookUiThreadMsg(m_broker, OutlookBrokerMsgType.ReceivedMsg); msg.Msg = transport.getRecv(); PostToUI(msg); } } } catch (Exception ex) { m_chattingFlag = false; CloseOutlookSock(); m_msgQueue.Clear(); if (ex is WorkerCancellationException) throw; OutlookUiThreadMsg msg = new OutlookUiThreadMsg(m_broker, OutlookBrokerMsgType.Disconnected); msg.Ex = ex; PostToUI(msg); } }
/// <summary> /// Block until the connection to Outlook is established. /// </summary> private void ConnectToOutlook() { Debug.Assert(!m_chattingFlag); Logging.Log("ConnectToOutlook() called."); while (!m_chattingFlag) { Logging.Log("In while loop."); // Close the Outlook socket if we have opened it inconclusively. CloseOutlookSock(); try { // Accept a connection. SelectSockets select = new SelectSockets(); select.AddRead(m_listenSock); Block(select); if (!select.InRead(m_listenSock)) continue; m_outlookSock = m_listenSock.Accept(); m_outlookSock.Blocking = false; Logging.Log("About to read MSO auth data."); // Read the authentication data. Timeout after 2 seconds. DateTime startTime = DateTime.Now; byte[] authSockData = new byte[m_secret.Length]; int nbRead = 0; while (nbRead != m_secret.Length) { Logging.Log("In Read while loop"); select = new SelectSockets(); select.AddRead(m_outlookSock); SetSelectTimeout(startTime, 2000, select, "no authentication data received"); Logging.Log("About to block"); Block(select); Logging.Log("Out of block"); int r = Base.SockRead(m_outlookSock, authSockData, nbRead, m_secret.Length - nbRead); if (r > 0) nbRead += r; Logging.Log("End Read while loop"); } if (!Base.ByteArrayEqual(m_secret, authSockData)) throw new Exception("invalid authentication data received"); Logging.Log("About to tell the broker we are connected."); // Inform the broker that we're connected. OutlookUiThreadMsg msg = new OutlookUiThreadMsg(m_broker, OutlookBrokerMsgType.Connected); msg.SessionID = ++m_sessionID; PostToUI(msg); // We're now chatting. m_chattingFlag = true; } catch (Exception ex) { if (ex is WorkerCancellationException) throw; Logging.Log(2, ex.Message); } } }
/// <summary> /// Handle a message received from the Outlook thread. /// </summary> public void HandleThreadMsg(OutlookUiThreadMsg msg) { Logging.Log("HandleThreadMsg() called."); // The thread is stopped or stopping, ignore the message. if (!IsThreadReady()) return; // Dispatch. try { if (msg.Type == OutlookBrokerMsgType.Connected) HandleConnectedToOutlook(msg.SessionID); else if (msg.Type == OutlookBrokerMsgType.Disconnected) HandleDisconnectedFromOutlook(msg.Ex); else if (msg.Type == OutlookBrokerMsgType.ReceivedMsg) HandleOutlookMessage(msg.Msg); } catch (Exception ex) { Base.HandleException(ex, true); } }