/// <summary> /// Find the first message and delivere it and if necessary acknowledge message /// Cut the reply string /// Returns false if message is not complete and we have to wait for remaining input /// </summary> /// <param name="incomeMessage"></param> /// <param name="sender"> /// The <see cref="RfNotificationListener"/> instance /// </param> /// <param name="e"> /// A <see cref="TcpListenerEventArgs"/> instance holding the socket connection /// </param> /// <returns></returns> bool decodeMessage(ref string reply, bool secondTry, object sender, TcpListenerEventArgs e) { string id = ""; string commandXMLTag = ""; Queue <string> debugData = new Queue <string> (); Queue <RfAlarm[]> alarmData = new Queue <RfAlarm[]> (); Queue <RfReport[]> reportData = new Queue <RfReport[]> (); // if we got a message check if we have to acknowledge it. if ((decodeAsyncData(ref reply, ref id, ref commandXMLTag, ref debugData, ref alarmData, ref reportData)) && e.ackMessage) { string handshakeReply = "<reply><id>" + id + "</id><resultCode>0</resultCode><" + commandXMLTag + "></reply>"; byte[] bytes = Encoding.ASCII.GetBytes(handshakeReply); int sentBytes = e.Socket.Send(bytes); if (RfReaderApi.showDebugInfo) { debugData.Enqueue("----aync nac: Ack----" + handshakeReply); } } RfReaderApi.CurrentApi.deliverMessages(debugData, alarmData, reportData); if (secondTry) { reply = ""; return(true); } if (0 < reply.Length) { return(false); } return(true); }
/// <summary> /// Gets called whenever a connection socket was accepted by the internal listener /// </summary> /// <param name="sender"> /// The <see cref="RfNotificationListener"/> instance /// </param> /// <param name="e"> /// A <see cref="TcpListenerEventArgs"/> instance holding the socket connection /// </param> void OnConnected(object sender, TcpListenerEventArgs e) { string reply = ""; bool secondTry = false; // implementation of nonblocking mode: // wait on receive for 500 ms. // if we doesn't implement timeout, our application will not shutdown. e.Socket.ReceiveTimeout = 500; while (!this.stopChannelListeners[e.ChannelName]) { try { // listen for data only if // - data is available // or - we doesn't have to decode a message if (e.Socket.Available > 0) { byte[] receiveBuffer = new byte[e.Socket.Available]; int bytesReceived = e.Socket.Receive(receiveBuffer); if (0 < bytesReceived) { // Decode incoming information and create streams without breaks. reply = reply + Encoding.ASCII.GetString(receiveBuffer, 0, bytesReceived); reply = reply.Replace("\0", ""); if (RfReaderApi.showDebugInfo) { RfReaderApi.CurrentApi.ProvideInformation("NC", InformationType.Debug, "----async nac: all----" + reply); } } } if (0 < reply.Length) { secondTry = !(decodeMessage(ref reply, secondTry, sender, e)); } } catch (SocketException /*ex */) { // No data available // empty message reply = ""; } // give other task time to run Thread.Sleep(1); } // end of while e.CloseConnection(); // Reenable socket receives this.stopChannelListeners[e.ChannelName] = false; }
/// <summary> /// Fire the Connected event if it exists. /// </summary> /// <param name="e"> /// See <see cref="TcpListenerEventArgs"/> for details /// </param> protected virtual void OnConnected(TcpListenerEventArgs e) { if (Connected != null) { try { Connected(this, e); } catch (Exception ex) { string strex = ex.Message; } } // Do not close the connection directly but simply wait for the called // handler to return. // As this method is a callback of an accepted socket we already have // a thread of our own. }