MSMQ Listener (windows service) can't receive messages independently after installation - msmq

I have two services running asynchronously. service1 is posting messages to MessageQueue which is in service2 (response queue).
Service2 is picking up each and every message from the queue and processing it.
problem is when ever service1 stops running because it finished sending messages.... service2 is not able to read the messages(still service2 is running) from the queue(still queue has some messages to read).
It is like service 2 becomes dormant when service one ended and the app is closed. Is this behavior expected?? Is there a solution.
I would like to have my service2(msmq listener) to continue to receive messages independently from Service 1.
using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.ServiceModel;
using System.ServiceProcess;
using System.Threading;
using LOGGER;
using MSMQ.INTERFACE;
using RightFax;
using Tools.Helper;
using Microsoft.VisualBasic;
using RFCOMAPILib;
using FAXHandlerClass = FAXHandlerClass;
using FAXHandlerState = CONTENT.SYSTEM.FAXHandlerState;
namespace MSMQ.LISTENER
{
public partial class Service1 : ServiceBase
{
public static FaxServer RFFaxApi;
private const string LogClass = "MSMQ.LISTENER.PROGRAM::";
private static bool _mBoolMustStop;
private static readonly RF2MQCounter Counter = new RF2MQCounter();
private static RFaxServerStatus _rightFaxServerStatus;
public static FAXHandlerState MThState = new FAXHandlerState();
private IMessageQueueHandler _queue;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
var logRoust = "OnStart";
Generic.ConfigParam = LoadConfig.Invoke(LogClass);
//Ping the server
PingReply rep;
var mac = PingServer.Mac(out rep, Generic.ConfigParam.RightFax.server);
if (rep != null)
{
Logger.Log(string.Format(#"Pinging {0} [{1}]", mac, rep.Address));
Logger.Log(string.Format("Reply From {0} : time={1} TTL={2}", rep.Address, rep.RoundtripTime,
rep.Options.Ttl));
//Connect to the Right Fax Server
Actions.Connect(LogClass, Counter, ref RFFaxApi);
//Start readin gthe queue
IMessageQueueHandler _queue = new Test();
var threadQueuet = new Thread(_queue.StartRead);
Logger.Log(string.Format("Start reading {0} queue...",
Generic.ConfigParam.MSMQ.responseQueue));
threadQueuet.Start();
}
else
{
Logger.Log(string.Format("Not able to get a reply From {0} : time={1} TTL={2}", rep.Address,
rep.RoundtripTime, rep.Options.Ttl));
}
}
catch (PingException e)
{
throw;
}
catch (Exception e)
{
Logger.Log(string.Format("{0} ::Not able to start the MSMQ.LISTENER Service on : {1} Mesage:: {2}", LogClass, Generic.ConfigParam.RightFax.server, e.Message ));
throw;
}
}
protected override void OnStop()
{
if (_queue != null)
_queue.StopRead();
Logger.Log(string.Format("Stopping MSMQ.LISTENER Service {0} queue...", Generic.ConfigParam.MSMQ.responseQueue));
}
/// <summary>
/// Connect to the Rightfax server
/// </summary>
/// <param name="ref">Used for logging the routine</param>
/// <returns>The RightFax server connection status</returns>
/// <remarks></remarks>
public static RFaxServerStatus ConnectToRightFax(string #ref)
{
var logRoust = #ref + LogClass + "CONNECTION::";
var retryCounter = 0;
Generic.ConfigParam = LoadConfig.Invoke(LogClass,Counter);
Logger.Log(string.Format("{0} - Connecting to {1} as user {2}", logRoust, Generic.ConfigParam.RightFax.server, ""));
_rightFaxServerStatus = RFaxServerStatus.Connecting;
try
{
if ((RFFaxApi != null))
RFFaxApi.CloseServer();
}
catch
{
//We do nothing.... We will destroy the object anyway
//return false;
}
RFFaxApi = null;
do
{
MThState.AddEventState = new FAXHandlerClass(FaxHandlerStateEnum.ConnectingRfax);
try
{
//**********************************************************************************************
// This section determines how quickly we try to reconnect
// Try the 1st 5 times 5 second apart
// the 2nd 5 times 30 seconds apart
// the 3rd 5 times 60 seconds apart
// every 300 seconds (5 mins) forever after that
//**********************************************************************************************
int sleepInterval;
if (retryCounter > 15)
{
sleepInterval = 300000;
}
else
{
if (retryCounter > 10)
{
sleepInterval = 60000;
}
else
{
sleepInterval = retryCounter > 5 ? 30000 : 5000;
}
}
//**************************************************
// Connect to the RightFax Server
//**************************************************
Logger.Log(string.Format("{0} - Attempt # {1}", logRoust, retryCounter));
if (retryCounter > 0)
{
Logger.Log(string.Format("{0} - Waiting # {1} seconds before trying to reconnect.", logRoust, sleepInterval / 1000));
Thread.Sleep(sleepInterval);
}
Logger.Log(string.Format("{0} - Initializing Connection to RightFax.", logRoust));
RFFaxApi = new FaxServer
{
ServerName = Generic.ConfigParam.RightFax.server.Trim(),
UseNTAuthentication = RFCOMAPILib.BoolType.False,
AuthorizationUserID = Generic.ConfigParam.RightFax.userID,
AuthorizationUserPassword = Generic.ConfigParam.RightFax.password,
Protocol = (CommunicationProtocolType)Generic.ConfigParam.RightFax.communicationProtocol
};
//Verify if the RightFax Service is runing before connecting
//var controller = new ServiceController("RightFax Server Module", _rfFaxApi.ServerName);
//if ((controller.Status.Equals(ServiceControllerStatus.Running)))
//{
try
{
RFFaxApi.OpenServer();
_rightFaxServerStatus = RFaxServerStatus.Connected;
retryCounter = 0;
Logger.Log(string.Format("{0} - Connected to {1} (V. {2}) as user {3}", logRoust, RFFaxApi.ServerName, RFFaxApi.Version, RFFaxApi.AuthorizationUserID));
}
catch (Exception ex)
{
Logger.Log(string.Format("{0} - ERROR Connected to {1} (V. {2}) as user {3} MESSAGE: {4}", logRoust, RFFaxApi.ServerName, RFFaxApi.Version, RFFaxApi.AuthorizationUserID, ex.Message));
}
}
catch (System.Runtime.InteropServices.COMException ex)
{
//Its OK not to end the loop. This is possibly a temporary error condition.
Logger.Log(string.Format("{0} - Connection failed Message: {1}", logRoust, ex.Message), EventLogEntryType.Warning);
}
catch (Exception ex)
{
if (Strings.InStr(ex.Source, "RFComAPI.FaxServer") > 0 | Strings.InStr(ex.Source, "Interop.RFCOMAPILib") > 0)
{
//Its OK not to end the loop. This is possibly a temporary error condition.
Logger.Log(string.Format("{0} - Connection failed : Message {1} ", logRoust, ex.Message), EventLogEntryType.Warning);
}
else
{
_rightFaxServerStatus = RFaxServerStatus.NotConnected;
Logger.Log(string.Format("{0} - Connection failed. Message: {1}", logRoust, ex.Message), EventLogEntryType.Error);
throw new Exception(string.Format("{0} - Connection failed. Message: {1}", logRoust, ex.Message));
}
}
finally
{
retryCounter += 1;
}
} while (!(_rightFaxServerStatus == RFaxServerStatus.Connected | _mBoolMustStop));
return _rightFaxServerStatus;
}
}
}
---------------------------------------------
using System.Net.NetworkInformation;
using System.ServiceProcess;
using System.Threading;
using LOGGER;
using MSMQ.INTERFACE;
using .RightFax;
using Tools.Helper;
using RFCOMAPILib;
using FAXHandlerState = HandlerState;
namespace MSMQ.LISTENER
{
static class Program
{
private const string LogClass = "MSMQ.LISTENER.PROGRAM::";
public static FaxServer RFFaxApi;
private static bool _mBoolMustStop;
private static readonly RF2MQCounter Counter = new RF2MQCounter();
private static RFaxServerStatus _rightFaxServerStatus;
public static FAXHandlerState MThState = new FAXHandlerState();
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Run();
//OR comment above to be able to Debug
//Uncomment below to start in debug mode
// Start();
}
private static void Run()
{
var servicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(servicesToRun);
}
public static void StartThreadProc(object stateInfo)
{
Start();
}
public static void Start()
{
try
{
var logRoust = "OnStart";
Generic.ConfigParam = LoadConfig.Invoke(LogClass);
//Ping the server
PingReply rep;
var mac = PingServer.Mac(out rep, Generic.ConfigParam.RightFax.server);
if (rep != null)
{
Logger.Log(string.Format(#"Pinging {0} [{1}]", mac, rep.Address));
Logger.Log(string.Format("Reply From {0} : time={1} TTL={2}", rep.Address, rep.RoundtripTime,
rep.Options.Ttl));
//Connect to the Right Fax Server
Actions.Connect(LogClass, Counter, ref RFFaxApi);
//Start readin gthe queue
IMessageQueueHandler _queue = new Isoconvoceresponse();
var threadQueuet = new Thread(_queue.StartRead);
Logger.Log(string.Format("Start reading {0} queue...",
Generic.ConfigParam.MSMQ.responseQueue));
threadQueuet.Start();
}
else
{
Logger.Log(string.Format("Not able to get a reply From {0} : time={1} TTL={2}", rep.Address,
rep.RoundtripTime, rep.Options.Ttl));
}
}
catch (PingException e)
{
throw;
}
}
}
}
___________________________
namespace MSMQ.INTERFACE
{
public interface IMessageQueueHandler
{
void StartRead();
void StopRead();
}
}
--------------
using System;
using System.Diagnostics;
using System.Globalization;
using System.Messaging;
using System.Net.NetworkInformation;
using System.ServiceModel;
using System.ServiceProcess;
using System.Threading;
using CONTENT.SYSTEM;
using LOGGER;
using MSMQ.INTERFACE;
using RightFax;
using RightFax.Tools.Helper;
using RFCOMAPILib;
using MessageQueue = System.Messaging.MessageQueue;
using RF2MQCounter = RF2MQCounter;
namespace MSMQ.LISTENER
{
public class Test : IMessageQueueHandler
{
private MessageQueue _queue;
private readonly string _queueName;
private const string LogClass = ".MSMQ.LISTENER::";
private readonly ManualResetEvent manualResetEvent = new ManualResetEvent(true);
private long handle ;
/// <summary>
///
/// </summary>
public Test()
{
const string logroust = LogClass + "Isoconvoceresponse";
Generic.ConfigParam = LoadConfig.Invoke(logroust);
_queueName =Generic.ConfigParam.MSMQ.responseQueue;
}
/// <summary>
///
/// </summary>
public void StartRead()
{
// System.Diagnostics.Debugger.Break();
const string logRoust = LogClass + "StartRead::";
try
{
Logger.Log(String.Format("{0} - Start Reading the {1} Queue .", logRoust, Generic.ConfigParam.MSMQ.responseQueue ));
_queue = new MessageQueue(_queueName) {Formatter = new XmlMessageFormatter(new[] {typeof (string)})};
_queue.MessageReadPropertyFilter.SetAll();
var objDefProps = new System.Messaging.DefaultPropertiesToSend
{
Priority = MessagePriority.High,
Recoverable = true,
UseDeadLetterQueue = true,
UseJournalQueue = true,
};
_queue.DefaultPropertiesToSend = objDefProps;
_queue.PeekCompleted += QueuePeekCompleted;
_queue.BeginPeek();
//_queue.ReceiveCompleted += QueueReceiveCompletedd;//Event handler
//_queue.BeginReceive();
}
catch (Exception ex)
{
Actions.SetGenericFlagOff(handle.ToString(CultureInfo.InvariantCulture),Generic.ConfigParam.dbConnectionString);
Logger.Log(
String.Format("{0} - Start Reading the {1} failed : Error: {2}.", logRoust, Generic.ConfigParam.MSMQ.responseQueue, ex.Message),
EventLogEntryType.Error);
throw;
}
}
public static void OnServiceFaulted(object sender, EventArgs e)
{
Logger.Log(string.Format("{0} ::Service Faulted: {1} Mesage:: {2}", LogClass, Generic.ConfigParam.RightFax.server, e.ToString()));
}
public void StopRead()
{//make the process synchronous before closing the queue
manualResetEvent.WaitOne();
if (_queue == null) return;
_queue.Close();
_queue = null;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void QueuePeekCompleted(object sender, PeekCompletedEventArgs e)
{
// System.Diagnostics.Debugger.Break();
const string logRoust = LogClass + "QueuePeekCompleted::";
var message = _queue.EndPeek(e.AsyncResult);
_queue.Receive();
_queue.BeginPeek();
var allMessagesOnResponseQueue = _queue.GetAllMessages();
foreach (var msg in allMessagesOnResponseQueue)
{
Logger.Log(String.Format("{0} - Messages QueuePeekCompleted event handler {1}", logRoust, message.Label + " - " + message.Id));
}
do
{
try
{
if (message.MessageType == MessageType.Acknowledgment)
switch (message.Acknowledgment)
{
case Acknowledgment.Purged:
Logger.Log("Message Purged {0}", message.Body.ToString());
break;
case Acknowledgment.QueueExceedMaximumSize:
Logger.Log("Message Queue Exceed MaximumSize {0}", message.Body.ToString());
break;
case Acknowledgment.QueuePurged:
Logger.Log("Message Queue Purged {0}", message.Body.ToString());
break;
case Acknowledgment.ReceiveTimeout:
Logger.Log("Message ReceiveTimeout {0}, Now restarting MSMQ.LISTENER Service",
message.Body.ToString());
var controller = new ServiceController("MSMQ.LISTENER", "STHA38994.iad.ca.inet");
if (controller.Status.Equals(ServiceControllerStatus.Running))
controller.Start();
break;
case Acknowledgment.ReachQueue:
Logger.Log("Message Reached Queue {0}", message.Body.ToString());
break;
case Acknowledgment.Receive:
Logger.Log("Message Received {0}", message.Body.ToString());
break;
}
/
if (message.MessageType == MessageType.Normal)
{
var messageDetail = message.Label.Split(' ');
var pdfFileDetails = messageDetail[1].Split('_');
handle = Convert.ToInt64(pdfFileDetails[0]);
var isSucessfull = false;
FaxServer faxServer = null;
if (MSMQ.LISTENER.Service1.RFFaxApi == null)
{
Generic.ConfigParam = LoadConfig.Invoke(LogClass);
var counter = new RF2MQCounter();
Actions.Connect(LogClass, counter, ref faxServer); //you can pass a null faxserver
}
if (faxServer != null)
{
try
{
Logger.Log("Getting Fax {0}", handle.ToString(CultureInfo.InvariantCulture));
var rfaxFax = Actions.GetFax(handle, ref faxServer);
Logger.Log("Getting Fax {0} SUCESS", handle.ToString(CultureInfo.InvariantCulture));
Generic.NumberOfRecordsSent++;
Logger.Log("Processing message {0}", handle.ToString(CultureInfo.InvariantCulture));
isSucessfull = RFServiceClass.ProcessMessage(message, ref rfaxFax);
Logger.Log("Processing message SUCESS {0}",
handle.ToString(CultureInfo.InvariantCulture));
}
catch (Exception ex)
{
Generic.NumberOfRecordsSent--;
Logger.Log(
String.Format("{0} - ERROR processinf fax from the queue.. {1}", logRoust,
ex.Message), EventLogEntryType.Error);
Actions.SetGenericFlagOff(handle.ToString(CultureInfo.InvariantCulture),
Generic.ConfigParam.dbConnectionString);
}
}
}
}
catch (MessageQueueException msq)
{
var messageDetail = message.Label.Split(' ');
var pdfFileDetails = messageDetail[1].Split('_');
long handle = Convert.ToInt64(pdfFileDetails[0]);
Actions.SetGenericFlagOff(handle.ToString(CultureInfo.InvariantCulture), Generic.ConfigParam.dbConnectionString);
switch (msq.MessageQueueErrorCode)
{
case MessageQueueErrorCode.IOTimeout:
Logger.Log(
String.Format("{0} - Error Message IOTimeout Exception: {1}.", logRoust, msq.Message),
EventLogEntryType.Error);
Actions.SetGenericFlagOff(handle.ToString(CultureInfo.InvariantCulture),Generic.ConfigParam.dbConnectionString );
break;
default:
Logger.Log(
String.Format("{0} - Error Message DEFAULT Exception: {1}.", logRoust, msq.Message),
EventLogEntryType.Error);
break;
}
}
catch (Exception ex)
{
Actions.SetGenericFlagOff(handle.ToString(CultureInfo.InvariantCulture), Generic.ConfigParam.dbConnectionString);
Logger.Log(
String.Format("{0} - Error QueuePeekCompleted: {1}.", logRoust, ex.Message),
EventLogEntryType.Error);
message = null;
}
} while (message != null);
}
}
public override string ToString()
{
return _queueName;
}
}
}

Related

Wrong client and server UDP connection in Java

I must to do chat server for my subject.
Where is my problem ?
I need to write UDP server class which should send and receive messages from users and transfer it to GUI
Second server should have methods for collect public keys of any user, changing owns ect. Additionally he should store this these keys
What do I have?
I have some code from first server, two Threads for sending and receiving messages and some code in client , but it isn't synchronized. And I don't know how to do it
This is some code from client main method: tfServer --> text field for getting this from user
InetAddress ia = InetAddress.getByName(tfServer.getText());
SenderThread sender = new SenderThread(ia,Integer.valueOf(tfPort.getText()));
sender.start();
ReceiverThread receiver = new ReceiverThread(sender.getSocket());
receiver.start();
First server code :
import java.net.* ;
public class Server {
int port;
private final static int PACKETSIZE = 100 ;
private boolean isStopped = false;
public Server(){
}
public Server(int port) {
this.port = port;
}
public void stop() {
this.isStopped = true;
}
public void start() {
try
{
DatagramSocket socket = new DatagramSocket(this.port) ;
System.out.println( "Serwer gotowy..." ) ;
if(!this.isStopped){
for( ;; ){
DatagramPacket packet = new DatagramPacket( new byte[PACKETSIZE], PACKETSIZE ) ;
socket.receive( packet ) ;
System.out.println( packet.getAddress() + " " + packet.getPort() + ": " + new String(packet.getData()) ) ;
socket.send( packet ) ;
}
}
}
catch( Exception e )
{
System.out.println( e ) ;
}
}
}
And class from first server to receive :
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiverThread extends Thread {
private DatagramSocket udpClientSocket;
private boolean stopped = false;
public ReceiverThread(DatagramSocket ds) throws SocketException {
this.udpClientSocket = ds;
}
public void halt() {
this.stopped = true;
}
public void run() {
byte[] receiveData = new byte[1024];
while (true) {
if (stopped)
return;
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
udpClientSocket.receive(receivePacket);
String serverReply = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("UDPClient: Response from Server: \"" + serverReply + "\"\n");
Thread.yield();
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
}
Second class from first server to send messages :
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiverThread extends Thread {
private DatagramSocket udpClientSocket;
private boolean stopped = false;
public ReceiverThread(DatagramSocket ds) throws SocketException {
this.udpClientSocket = ds;
}
public void halt() {
this.stopped = true;
}
public void run() {
byte[] receiveData = new byte[1024];
while (true) {
if (stopped)
return;
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
udpClientSocket.receive(receivePacket);
String serverReply = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("UDPClient: Response from Server: \"" + serverReply + "\"\n");
Thread.yield();
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
}
And server PKI :
public class ServerPKI {
}

Service-Unavailable(503) Error in Smack XEP-0198: Stream Management

I am using below class to enable stream management("urn:xmpp:sm:3") in our ejabberd server(we have latest version of ejabberd). But when I send the Enable packet to server it says Service Unavailable(503). But when I use "yaxim" it works perfectly. Please help me to solve this problem. Thanks.
public class XmppStreamHandler {
public static final String URN_SM_3 = "urn:xmpp:sm:3";
private static final int MAX_OUTGOING_QUEUE_SIZE = 20;
private static final int OUTGOING_FILL_RATIO = 4;
private XMPPConnection mConnection;
private boolean isSmAvailable = false;
private boolean isSmEnabled = false;
private boolean isOutgoingSmEnabled = false;
private long previousIncomingStanzaCount = -1;
private String sessionId;
private long incomingStanzaCount = 0;
private long outgoingStanzaCount = 0;
private Queue<Packet> outgoingQueue;
private int maxOutgoingQueueSize = MAX_OUTGOING_QUEUE_SIZE;
private ConnectionListener mConnectionListener;
public XmppStreamHandler(XMPPConnection connection, ConnectionListener connectionListener) {
mConnection = connection;
mConnectionListener = connectionListener;
startListening();
}
/** Perform a quick shutdown of the XMPPConnection if a resume is possible */
public void quickShutdown() {
if (isResumePossible()) {
mConnection.quickShutdown();
// We will not necessarily get any notification from a quickShutdown, so adjust our state here.
closeOnError();
} else {
mConnection.shutdown();
}
}
public void setMaxOutgoingQueueSize(int maxOutgoingQueueSize) {
this.maxOutgoingQueueSize = maxOutgoingQueueSize;
}
public boolean isResumePossible() {
return sessionId != null;
}
public boolean isResumePending() {
return isResumePossible() && !isSmEnabled;
}
public static void addExtensionProviders() {
addSimplePacketExtension("sm", URN_SM_3);
addSimplePacketExtension("r", URN_SM_3);
addSimplePacketExtension("a", URN_SM_3);
addSimplePacketExtension("enabled", URN_SM_3);
addSimplePacketExtension("resumed", URN_SM_3);
addSimplePacketExtension("failed", URN_SM_3);
}
public void notifyInitialLogin() {
if (sessionId == null && isSmAvailable)
sendEnablePacket();
}
private void sendEnablePacket() {
debug("sm send enable " + sessionId);
if (sessionId != null) {
isOutgoingSmEnabled = true;
// TODO binding
StreamHandlingPacket resumePacket = new StreamHandlingPacket("resume", URN_SM_3);
resumePacket.addAttribute("h", String.valueOf(previousIncomingStanzaCount));
resumePacket.addAttribute("previd", sessionId);
mConnection.sendPacket(resumePacket);
} else {
outgoingStanzaCount = 0;
outgoingQueue = new ConcurrentLinkedQueue<Packet>();
isOutgoingSmEnabled = true;
StreamHandlingPacket enablePacket = new StreamHandlingPacket("enable", URN_SM_3);
enablePacket.addAttribute("resume", "true");
mConnection.sendPacket(enablePacket);
}
}
private void closeOnError() {
if (isSmEnabled && sessionId != null) {
previousIncomingStanzaCount = incomingStanzaCount;
}
isSmEnabled = false;
isOutgoingSmEnabled = false;
isSmAvailable = false;
}
private void startListening() {
mConnection.forceAddConnectionListener(new ConnectionListener() {
public void reconnectionSuccessful() {
}
public void reconnectionFailed(Exception e) {
}
public void reconnectingIn(int seconds) {
}
public void connectionClosedOnError(Exception e) {
if (e instanceof XMPPException &&
((XMPPException)e).getStreamError() != null) {
// Non-resumable stream error
close();
} else {
// Resumable
closeOnError();
}
}
public void connectionClosed() {
previousIncomingStanzaCount = -1;
}
});
mConnection.addPacketSendingListener(new PacketListener() {
public void processPacket(Packet packet) {
// Ignore our own request for acks - they are not counted
if (!isStanza(packet)) {
trace("send " + packet.toXML());
return;
}
if (isOutgoingSmEnabled && !outgoingQueue.contains(packet)) {
outgoingStanzaCount++;
outgoingQueue.add(packet);
trace("send " + outgoingStanzaCount + " : " + packet.toXML());
// Don't let the queue grow beyond max size. Request acks and drop old packets
// if acks are not coming.
if (outgoingQueue.size() >= maxOutgoingQueueSize / OUTGOING_FILL_RATIO) {
mConnection.sendPacket(new StreamHandlingPacket("r", URN_SM_3));
}
if (outgoingQueue.size() > maxOutgoingQueueSize) {
// Log.e(XmppConnection.TAG, "not receiving acks? outgoing queue full");
outgoingQueue.remove();
}
} else if (isOutgoingSmEnabled && outgoingQueue.contains(packet)) {
outgoingStanzaCount++;
trace("send DUPLICATE " + outgoingStanzaCount + " : " + packet.toXML());
} else {
trace("send " + packet.toXML());
}
}
}, new PacketFilter() {
public boolean accept(Packet packet) {
return true;
}
});
mConnection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
if (isSmEnabled && isStanza(packet)) {
incomingStanzaCount++;
trace("recv " + incomingStanzaCount + " : " + packet.toXML());
} else {
trace("recv " + packet.toXML());
}
if (packet instanceof StreamHandlingPacket) {
StreamHandlingPacket shPacket = (StreamHandlingPacket) packet;
String name = shPacket.getElementName();
if ("sm".equals(name)) {
debug("sm avail");
isSmAvailable = true;
if (sessionId != null)
sendEnablePacket();
} else if ("r".equals(name)) {
StreamHandlingPacket ackPacket = new StreamHandlingPacket("a", URN_SM_3);
ackPacket.addAttribute("h", String.valueOf(incomingStanzaCount));
mConnection.sendPacket(ackPacket);
} else if ("a".equals(name)) {
long ackCount = Long.valueOf(shPacket.getAttribute("h"));
removeOutgoingAcked(ackCount);
trace(outgoingQueue.size() + " in outgoing queue after ack");
} else if ("enabled".equals(name)) {
incomingStanzaCount = 0;
isSmEnabled = true;
mConnection.getRoster().setOfflineOnError(false);
String resume = shPacket.getAttribute("resume");
if ("true".equals(resume) || "1".equals(resume)) {
sessionId = shPacket.getAttribute("id");
}
debug("sm enabled " + sessionId);
} else if ("resumed".equals(name)) {
debug("sm resumed");
incomingStanzaCount = previousIncomingStanzaCount;
long resumeStanzaCount = Long.valueOf(shPacket.getAttribute("h"));
// Removed acked packets
removeOutgoingAcked(resumeStanzaCount);
trace(outgoingQueue.size() + " in outgoing queue after resume");
// Resend any unacked packets
for (Packet resendPacket : outgoingQueue) {
mConnection.sendPacket(resendPacket);
}
// Enable only after resend, so that the interceptor does not
// queue these again or increment outgoingStanzaCount.
isSmEnabled = true;
// Re-notify the listener - we are really ready for packets now
// Before this point, isSuspendPending() was true, and the listener should have
// ignored reconnectionSuccessful() from XMPPConnection.
mConnectionListener.reconnectionSuccessful();
} else if ("failed".equals(name)) {
// Failed, shutdown and the parent will retry
debug("sm failed");
mConnection.getRoster().setOfflineOnError(true);
mConnection.getRoster().setOfflinePresences();
sessionId = null;
mConnection.shutdown();
// isSmEnabled / isOutgoingSmEnabled are already false
}
}
}
}, new PacketFilter() {
public boolean accept(Packet packet) {
return true;
}
});
}
private void removeOutgoingAcked(long ackCount) {
if (ackCount > outgoingStanzaCount) {
// Log.e(XmppConnection.TAG,
// "got ack of " + ackCount + " but only sent " + outgoingStanzaCount);
// Reset the outgoing count here in a feeble attempt to re-sync. All bets
// are off.
outgoingStanzaCount = ackCount;
}
int size = outgoingQueue.size();
while (size > outgoingStanzaCount - ackCount) {
outgoingQueue.remove();
size--;
}
}
private static void addSimplePacketExtension(final String name, final String namespace) {
ProviderManager.getInstance().addExtensionProvider(name, namespace,
new PacketExtensionProvider() {
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
StreamHandlingPacket packet = new StreamHandlingPacket(name, namespace);
int attributeCount = parser.getAttributeCount();
for (int i = 0; i < attributeCount; i++) {
packet.addAttribute(parser.getAttributeName(i),
parser.getAttributeValue(i));
}
return packet;
}
});
}
private void debug(String message) {
System.out.println(message);
}
private void trace(String message) {
System.out.println(message);
}
public static class StreamHandlingPacket extends UnknownPacket {
private String name;
private String namespace;
Map<String, String> attributes;
StreamHandlingPacket(String name, String namespace) {
this.name = name;
this.namespace = namespace;
attributes = Collections.emptyMap();
}
public void addAttribute(String name, String value) {
if (attributes == Collections.EMPTY_MAP)
attributes = new HashMap<String, String>();
attributes.put(name, value);
}
public String getAttribute(String name) {
return attributes.get(name);
}
public String getNamespace() {
return namespace;
}
public String getElementName() {
return name;
}
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<").append(getElementName());
// TODO Xmlns??
if (getNamespace() != null) {
buf.append(" xmlns=\"").append(getNamespace()).append("\"");
}
for (String key : attributes.keySet()) {
buf.append(" ").append(key).append("=\"")
.append(StringUtils.escapeForXML(attributes.get(key))).append("\"");
}
buf.append("/>");
return buf.toString();
}
}
/** Returns true if the packet is a Stanza as defined in RFC-6121 - a Message, IQ or Presence packet. */
public static boolean isStanza(Packet packet) {
if (packet instanceof Message)
return true;
if (packet instanceof IQ)
return true;
if (packet instanceof Presence)
return true;
return false;
}
public void queue(Packet packet) {
if (outgoingQueue.size() >= maxOutgoingQueueSize) {
System.out.println("outgoing queue full");
return;
}
outgoingStanzaCount++;
outgoingQueue.add(packet);
}
private void close() {
isSmEnabled = false;
isOutgoingSmEnabled = false;
sessionId = null;
}
}
when I send the Enable packet to server it says Service
Unavailable(503)
Service Unavailable means that the service is unavailable on the server. Does ejabberd support XEP-198? Did you enable it?
You should also consider switching to Smack 4.1.0-alpha, which also runs on Android and comes with Stream Management support. yaxim will soon switch to from it's custom XmppStreamHandler implementation to Smack 4.1.

Libusbdotnet HID Read (Event Driven) Error

I used LibUSbDotNet for read USB data from my Hardware using Event Driven operation. My hardware pumps out data at two different intervals. (2000 ms and 300 ms). The buffer size is 7 bytes.
The code works fine for sometimes afterwards the reading is slowed. instead of 2000 and 300 ms the data receives at 4000 and 2000 ms.
Please help me resolve this issue guys...
regards
John
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibUsbDotNet;
using LibUsbDotNet.DeviceNotify;
using LibUsbDotNet.Main;
namespace ATE_BackEnd
{
public partial class Main_Form : Form
{
public static IDeviceNotifier UsbDeviceNotifier = DeviceNotifier.OpenDeviceNotifier();
UsbDeviceFinder MyUsbFinder;
UsbDevice MyUsbDevice;
UsbEndpointReader EPReader;
UsbEndpointWriter EPWriter;
int bytesWritten;
public DateTime LastDataEventDate = DateTime.Now;
public Main_Form()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
UsbDeviceNotifier.OnDeviceNotify += OnDeviceNotifyEvent;
}
void OpenUSB(int VendorID, int ProductID)
{
toolStripStatusLabel.Text = "Opening USB";
MyUsbFinder = new UsbDeviceFinder(VendorID, ProductID);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
if (MyUsbDevice == null) { USBConnection_label.Text = "USB Not Connected"; CloseUSB(); }
else
{
USBConnection_label.Text = "USB Connected";
USBInfo_label.Text = "VID = " + MyUsbDevice.Info.Descriptor.VendorID.ToString() +
", PID = " + MyUsbDevice.Info.Descriptor.ProductID.ToString();
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
EPReader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01, 7);
EPWriter = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
EPReader.DataReceived += OnUsbDataReceived;
EPReader.DataReceivedEnabled = true;
}
}
void WriteUSB(int Site)
{
toolStripStatusLabel.Text = "Writing Data...";
ErrorCode ECWriter = EPWriter.Write(Encoding.Default.GetBytes(Site.ToString()), 100, out bytesWritten);
if (ECWriter != ErrorCode.None) throw new Exception(UsbDevice.LastErrorString);
}
void CloseUSB()
{
toolStripStatusLabel.Text = "Closing USB";
if (MyUsbDevice != null)
{
if (MyUsbDevice.IsOpen)
{
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.ReleaseInterface(0);
}
MyUsbDevice.Close();
}
EPReader.DataReceived -= OnUsbDataReceived;
EPReader.DataReceivedEnabled = false;
EPReader.Dispose();
EPWriter.Dispose();
}
MyUsbDevice = null;
UsbDevice.Exit();
}
void OnDeviceNotifyEvent(object sender, DeviceNotifyEventArgs e)
{
toolStripStatusLabel.Text = "Device Notify Message: " + e.EventType.ToString();
if (e.EventType.ToString() == "DeviceRemoveComplete") { USBConnection_label.Text = "USB Disconnected"; CloseUSB(); }
else if (e.EventType.ToString() == "DeviceArrival") { USBConnection_label.Text = "USB Connected"; OpenUSB(4660, 1); }
}
void OnUsbDataReceived(object sender, EndpointDataEventArgs e)
{
toolStripStatusLabel.Text = "Receiving Data!!!";
byte[] s1stat = e.Buffer;
S1SOT_textBox.Text = s1stat[0].ToString();
S2SOT_textBox.Text = s1stat[1].ToString();
S1EOT_textBox.Text = s1stat[2].ToString();
S2EOT_textBox.Text = s1stat[3].ToString();
S1BIN_textBox.Text = s1stat[4].ToString();
S2BIN_textBox.Text = s1stat[5].ToString();
TowerLamp_textBox.Text = s1stat[6].ToString();
Time_label.Text = (DateTime.Now - LastDataEventDate).TotalMilliseconds.ToString();
LastDataEventDate = DateTime.Now;
}
private void Main_Form_FormClosing(object sender, FormClosingEventArgs e)
{
toolStripStatusLabel.Text = "Closing App";
CloseUSB();
}
private void Main_Form_Load(object sender, EventArgs e)
{
toolStripStatusLabel.Text = "Opening App";
OpenUSB(4660, 1);
}
private void Write_button_Click(object sender, EventArgs e)
{
CloseUSB();
OpenUSB(4660, 1);
WriteUSB(Write_comboBox.SelectedIndex+1);
}
}
}

Asynchronous Client Socket ManualResetEvent holding up execution

I am attempting to utilize MSDN's Asynchronous Client Socket code sample to connect and control some home equipment. As I understand, the sample code's ReceiveCallback method uses an instance of the EventWaitHandle ManualResetEvent and the method receiveDone.WaitOne() to hold processing of the current thread until the thread receives a signal that all of the socket's data has been transmitted from the remote device. After all of the socket's data has been transmitted (the socket's data is empty and bytesRead = 0), the Waithandle is removed and the application continues processing.
Unfortunately, by stepping-through the execution of the code, it appears that after the last time that the client returns data from the remote device, ReceiveCallback never returns to see if the data-queue is empty (i.e. bytesRead = 0), and thus never enters the "else" condition in ReceiveCallback where the state of the ManualResetEvent would have been reset and the application would have continued to process. Thus, since it never enters the "else" condition, ManualResetEvent is never reset and the application freezes.
Although I can remove the "receiveDone.WaitOne()" method from the code - permitting execution without waiting for the ManualResetEvent's notification that all of the data has been received; this returns a data-string from the equipment that is typically incomplete.
Am I using this code sample incorrectly? Has anyone seen this before or had any experience on how to work-around this issue?
7/14/2012 - UPDATE: After further testing of the MSDN's Asynchronous Client Socket Example, it became clear that ReceiveCallback actually re-polls the port and the "bytesRead = 0" condition is satisfied only when the socket is released (i.e. client.Shutdown(SocketShutdown.Both); client.Close(); ). If I understand this correctly, this means that the connection has to be closed to get past the receiveDone.WaitOne() method. If the connection is closed to satisfy the WaitOne() Waithandle, it totally defeats the purpose of the application in that I had been hoping to leave the connection open so that the application could listen for equipment updates, which happen continually.
7/16/2012 - UPDATE: I have written to Microsoft Tech Support who have responded that "We're doing research on this issue. It might take some time before we get back to you." As such, it seems that it doesn't appear that this challenge can be resolved at this time through massaging this code.
Without the availability of the Asynchronous Client Socket example code as a foundation for writing asynchronous communication procedures, may I ask if anyone can please suggest a replacement routine that is more reliable? There are three pieces of equipment, each with it's own ip-address and port number. Thus, it would be ideal if a class could be utilized, where an instance could be created for each device. Additionally, the port must remain open to receive spontaneous updates continually sent by the equipment. Lastly, the updates do not have a end character or defined length signalling that the transmission of the message is complete, thus the routine must continually poll the port for available data. Any advice or suggestions would be greatly appreciated.
7/18/2012 - WORKAROUND: After spending a considerable amount of time attempting to get the MSDN's Asynchronous Client Socket code sample working, it became clear that I would have to look elsewhere to get the device responses continuously recognized by the program. In the hope to save someone else the brain-damage, I have included the work-around that I used which seems to work well to this point. If anyone has any suggestions, please don't hesitate to add to this question!
//
// ORIGINAL CODE ATTEMPT
//
public static Socket LutronClient;
public static String LutronResponse = String.Empty;
private const int LutronPort = 4999;
private const string LutronIP = "192.168.1.71";
private static ManualResetEvent LutronConnectDone = new ManualResetEvent(false);
private static ManualResetEvent LutronSendDone = new ManualResetEvent(false);
private static ManualResetEvent LutronReceiveDone = new ManualResetEvent(false);
private static void StartLutronClient()
{
try
{
var lutronIPAddress = IPAddress.Parse(LutronIP);
var lutronRemoteEP = new IPEndPoint(lutronIPAddress, LutronPort);
LutronClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
LutronClient.BeginConnect(lutronRemoteEP, LutronConnectCallback, LutronClient);
LutronConnectDone.WaitOne();
LutronSend(LutronClient, "sdl,14,100,0,S2\x0d");
LutronSendDone.WaitOne();
LutronReceive(LutronClient);
LutronReceiveDone.WaitOne(new TimeSpan(5000));
MessageBox.Show("Response received from Lutron: " + LutronResponse);
txtBoxLutron.Text = LutronResponse;
LutronClient.Shutdown(SocketShutdown.Both);
LutronClient.Close();
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
private static void LutronConnectCallback(IAsyncResult lutronAr)
{
try
{
var lutronClient = (Socket)lutronAr.AsyncState;
lutronClient.EndConnect(lutronAr);
LutronConnectDone.Set();
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
private static void LutronReceive(Socket lutronClient)
{
try
{
var lutronState = new LutronStateObject { LutronWorkSocket = lutronClient };
lutronClient.BeginReceive(lutronState.LutronBuffer, 0, LutronStateObject.BufferSize, 0, new AsyncCallback(LutronReceiveCallback), lutronState);
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
private static void LutronReceiveCallback(IAsyncResult lutronAR)
{
try
{
var lutronState = (LutronStateObject)lutronAR.AsyncState;
var lutronClient = lutronState.LutronWorkSocket;
var bytesRead = lutronClient.EndReceive(lutronAR);
if (bytesRead > 0)
{
lutronState.LutronStringBuilder.AppendLine(Encoding.ASCII.GetString(lutronState.LutronBuffer, 0, bytesRead));
lutronClient.BeginReceive(lutronState.LutronBuffer, 0, LutronStateObject.BufferSize, 0, new AsyncCallback(LutronReceiveCallback), lutronState);
}
else
{
if (lutronState.LutronStringBuilder.Length > 0) { LutronResponse = lutronState.LutronStringBuilder.ToString(); }
LutronReceiveDone.Set();
}
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
public static void LutronSend(Socket client, String data)
{
var byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0, LutronSendCallback, client);
}
private static void LutronSendCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
var bytesSent = client.EndSend(ar);
LutronSendDone.Set();
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
public class LutronStateObject
{
public Socket LutronWorkSocket;
public const int BufferSize = 256;
public byte[] LutronBuffer = new byte[BufferSize];
public StringBuilder LutronStringBuilder = new StringBuilder();
}
}
This is the work-around I used:
//
// WORK-AROUND
//
using System;
using System.Windows.Forms;
namespace _GlobalCacheInterface
{
public partial class GlobalCacheDataScreen : Form
{
//Interface objects
private static GC_Interface _lutronInterface;
private const int LutronPort = 4999;
private const string LutronIP = "192.168.1.71";
delegate void ThreadSafeLutronCallback(string text);
private static GC_Interface _elanInterface;
private const int ElanPort = 4998;
private const string ElanIP = "192.168.1.70";
delegate void ThreadSafeElanCallback(string text);
private static GC_Interface _tuneSuiteInterface;
private const int TuneSuitePort = 5000;
private const string TuneSuiteIP = "192.168.1.70";
delegate void ThreadSafeTuneSuiteCallback(string text);
public GlobalCacheDataScreen()
{
InitializeComponent();
_lutronInterface = new GC_Interface(LutronIP, LutronPort);
_elanInterface = new GC_Interface(ElanIP, ElanPort);
_tuneSuiteInterface = new GC_Interface(TuneSuiteIP, TuneSuitePort);
// Create event handlers to notify application of available updated information.
_lutronInterface.DataAvailable += (s, e) => ThreadSafeTxtBoxLutron(_lutronInterface._returnString);
_elanInterface.DataAvailable += (s, e) => ThreadSafeTxtBoxElan(_elanInterface._returnString);
_tuneSuiteInterface.DataAvailable += (s, e) => ThreadSafeTxtBoxTuneSuite(_tuneSuiteInterface._returnString);
_lutronInterface.Connected += (s, e) => UpdateUI();
_elanInterface.Connected += (s, e) => UpdateUI();
_tuneSuiteInterface.Connected += (s, e) => UpdateUI();
UpdateUI();
}
private void UpdateUI()
{
_buttonConnectToLutron.Enabled = !_lutronInterface._isConnected;
_buttonConnectToElan.Enabled = !_elanInterface._isConnected;
_buttonConnectToTuneSuite.Enabled = !_tuneSuiteInterface._isConnected;
_buttonDisconnectFromLutron.Enabled = _lutronInterface._isConnected;
_buttonDisconnectFromElan.Enabled = _elanInterface._isConnected;
_buttonDisconnectFromTuneSuite.Enabled = _tuneSuiteInterface._isConnected;
string connectLutronStatus = _lutronInterface._isConnected ? "Connected" : "Not Connected";
string connectElanStatus = _elanInterface._isConnected ? "Connected" : "Not Connected";
string connectTuneSuiteStatus = _tuneSuiteInterface._isConnected ? "Connected" : "Not Connected";
_textBoxLutronConnectStatus.Text = connectLutronStatus;
_textBoxElanConnectStatus.Text = connectElanStatus;
_textBoxTuneSuiteConnectStatus.Text = connectTuneSuiteStatus;
}
private void ThreadSafeTxtBoxLutron(string message) { if (_lutronRichTextRxMessage.InvokeRequired) { var d = new ThreadSafeLutronCallback(ThreadSafeTxtBoxLutron); _lutronRichTextRxMessage.Invoke(d, new object[] { message }); } else { _lutronRichTextRxMessage.Text = message; } }
private void ThreadSafeTxtBoxElan(string message) { if (_elanRichTextRxMessage.InvokeRequired) { var d = new ThreadSafeElanCallback(ThreadSafeTxtBoxElan); _elanRichTextRxMessage.Invoke(d, new object[] { message }); } else { _elanRichTextRxMessage.Text = message; if (message.EndsWith("\r")) { MessageBoxEx.Show(message, "Message from Lutron Elan", 1000); } } }
private void ThreadSafeTxtBoxTuneSuite(string message) { if (_tuneSuiteRichTextRxMessage.InvokeRequired) { var d = new ThreadSafeTuneSuiteCallback(ThreadSafeTxtBoxTuneSuite); _tuneSuiteRichTextRxMessage.Invoke(d, new object[] { message }); } else { _tuneSuiteRichTextRxMessage.Text = message; if (message.EndsWith("\r")) { MessageBoxEx.Show(message, "Message from TuneSuite", 1000); } } }
private void _buttonConnectToLutron_Click(object sender, EventArgs e) { _lutronInterface.Connect(); }
private void _buttonDisconnectFromLutron_Click(object sender, EventArgs e) { _lutronInterface.Disconnect(); }
private void _buttonConnectToElan_Click(object sender, EventArgs e) { _elanInterface.Connect(); }
private void _buttonDisconnectFromElan_Click(object sender, EventArgs e) { _elanInterface.Disconnect(); }
private void _buttonConnectToTuneSuite_Click(object sender, EventArgs e) { _tuneSuiteInterface.Connect(); }
private void _buttonDisconnectFromTuneSuite_Click(object sender, EventArgs e) { _tuneSuiteInterface.Disconnect(); }
private void _buttonLutronSendMessage_Click(object sender, EventArgs e) { _lutronInterface.SendCommand(_lutronRichTextTxMessage.Text); }
private void _buttonElanSendMessage_Click(object sender, EventArgs e) { _elanInterface.SendCommand(_elanRichTextTxMessage.Text); }
private void _buttonTuneSuiteSendMessage_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand(_elanRichTextTxMessage.Text); }
private void _buttonLightOn_Click(object sender, EventArgs e) { _lutronInterface.SendCommand("sdl,14,100,0,S2"); }
private void _buttonLightOff_Click(object sender, EventArgs e) { _lutronInterface.SendCommand("sdl,14,0,0,S2"); }
private void _buttonStereoOnOff_Click(object sender, EventArgs e) { _elanInterface.SendCommand("sendir,4:3,1,40000,4,1,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,800"); }
private void _button30_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand("\xB8\x4D\xB5\x33\x30\x00\x30\x21\xB8"); }
private void _button31_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand("\xB8\x4D\xB5\x33\x31\x00\x30\x21\xB8"); }
private void _button26_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand("\xB8\x4D\xB5\x32\x36\x00\x30\x21\xB8"); }
}
}
and the GC_Interface class:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace _GlobalCacheInterface
{
class GC_Interface
{
// Declare an event handler to notify when updates are available.
public event EventHandler<EventArgs> DataAvailable;
public string _returnString = "";
// Declare an event handler to notify status of connection.
public event EventHandler<EventArgs> Connected;
public bool _isConnected;
public AsyncCallback ReceiveCallback;
public Socket Client;
private string _ipAddress;
private int _port;
private bool _waitForEndCharacter;
private byte _endCharacter;
byte[] m_DataBuffer = new byte[10];
IAsyncResult m_Result;
public GC_Interface(string ipAddress, int port) { Init(ipAddress, port, false, 0); }
private void Init(string ipAddress, int port, bool waitForEndCharacter, byte endCharacter)
{
_ipAddress = ipAddress;
_port = port;
_waitForEndCharacter = waitForEndCharacter;
_endCharacter = endCharacter;
_isConnected = false;
}
public bool Connect()
{
try
{
// Create a TCP/IP socket.
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Establish the remote endpoint for the socket.
var address = IPAddress.Parse(_ipAddress);
var remoteEP = new IPEndPoint(address, _port);
// Connect to the remote endpoint.
Client.Connect(remoteEP);
if (Client.Connected)
{
_isConnected = true;
ConnectedEventHandler();
WaitForData();
}
return true;
}
catch (SocketException se) { MessageBox.Show("\n connection failed, is the server running?\n" + se.Message ); return false; }
}
public bool SendCommand(string command)
{
try
{
// Convert the string data to byte data using ASCII encoding.
var byteData = Encoding.Default.GetBytes(command);
// Add a carraige-return to the end.
var newArray = new byte[byteData.Length + 1];
byteData.CopyTo(newArray, 0);
newArray[newArray.Length - 1] = 13;
if (Client == null) { return false; }
Client.Send(newArray);
return true;
}
catch (SocketException se) { MessageBox.Show(se.Message); return false; }
}
public void WaitForData()
{
try
{
if (ReceiveCallback == null) { ReceiveCallback = new AsyncCallback(OnDataReceived); }
var theSocPkt = new SocketPacket { thisSocket = Client };
m_Result = Client.BeginReceive(theSocPkt.DataBuffer, 0, theSocPkt.DataBuffer.Length, SocketFlags.None, ReceiveCallback, theSocPkt);
}
catch (SocketException se) { MessageBox.Show(se.Message); }
}
public class SocketPacket
{
public System.Net.Sockets.Socket thisSocket;
public byte[] DataBuffer = new byte[1];
}
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
var iRx = theSockId.thisSocket.EndReceive(asyn);
char[] Chars = new char[iRx + 1];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int CharLen = d.GetChars(theSockId.DataBuffer, 0, iRx, Chars, 0);
System.String szData = new System.String(Chars);
_returnString = _returnString + szData.Replace("\0", "");
// When an update is received, raise DataAvailable event
DataAvailableEventHandler();
WaitForData();
}
catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); }
catch (SocketException se) { MessageBox.Show(se.Message); }
}
public bool Disconnect()
{
try
{
if (Client == null) { return false; }
Client.Close();
Client = null;
_isConnected = false;
return true;
}
catch (Exception) { return false; }
}
protected virtual void DataAvailableEventHandler()
{
var handler = DataAvailable;
if (handler != null) { handler(this, EventArgs.Empty); }
}
protected virtual void ConnectedEventHandler()
{
var handler = Connected;
if (handler != null) { handler(this, EventArgs.Empty); }
}
}
}
I had the same issue, adding an Available check to the code fixed my problem. Below is the revised code.
private static void ReceiveCallback( IAsyncResult ar ) {
try {
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0) {
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Check if there is anymore data on the socket
if (client.Available > 0) {
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
}
if (bytesRead == 0 || client.Available == 0) {
if (state.sb.Length > 1) {
response = state.sb.ToString();
}
receiveDone.Set();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
Hope that helps.
I'm sidestepping the question here. I try to answer what you need, not what you ask for:
Use synchronous code. It will be easier to understand, you don't need callbacks or events. Also, for low thread counts, it is likely to perform better.
You also avoid bugs that you have in your current code. If an exception occurs your computation never completes. Synchronous code does not have that problem.

Instance-Specific EventHandler to provide data visibility beyond the Class-Level

May I ask for help with the following?
I am attempting to connect and control three pieces of household electronic equipment by computer through a GlobalCache GC-100 and iTach. As you will see in the following code, I created a class ("GlobalCacheAdapter") that can communicate and control the equipment, and created an instance of the class for each piece of equipment. Although each instance seems to work well with communicating and in controlling each piece of equipment, the *feedback returned from the equipment* seems only to be visible at the defining class level's - "ReaderThreadProc" procedure. Further processing of the feedback is required for each piece of equipment and I am uncertain as to how to forward this feedback at the equipment specific instance-level. I suspect that an instance-specific EventHandler will need to be implemented; however I am not aware as to how to implement this type of instance-specific EventHandler in order to complete processing and update the appropriate controls.
Any help wold be greatly appreciated.
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// Create three new instances of GlobalCacheAdaptor and connect.
// GC-100 (Elan) 192.168.1.70 4998
// GC-100 (TuneSuite) 192.168.1.70 5000
// GC iTach (Lighting) 192.168.1.71 4999
private GlobalCacheAdaptor elanGlobalCacheAdaptor;
private GlobalCacheAdaptor tuneSuiteGlobalCacheAdaptor;
private GlobalCacheAdaptor lutronGlobalCacheAdaptor;
public Form1()
{
InitializeComponent();
elanGlobalCacheAdaptor = new GlobalCacheAdaptor();
elanGlobalCacheAdaptor.ConnectToDevice(IPAddress.Parse("192.168.1.70"), 4998);
tuneSuiteGlobalCacheAdaptor = new GlobalCacheAdaptor();
tuneSuiteGlobalCacheAdaptor.ConnectToDevice(IPAddress.Parse("192.168.1.70"), 5000);
lutronGlobalCacheAdaptor = new GlobalCacheAdaptor();
lutronGlobalCacheAdaptor.ConnectToDevice(IPAddress.Parse("192.168.1.71"), 4999);
elanTextBox.Text = elanGlobalCacheAdaptor._line;
tuneSuiteTextBox.Text = tuneSuiteGlobalCacheAdaptor._line;
lutronTextBox.Text = lutronGlobalCacheAdaptor._line;
}
private void btnZoneOnOff_Click(object sender, EventArgs e) { elanGlobalCacheAdaptor.SendMessage("sendir,4:3,1,40000,4,1,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,800" + Environment.NewLine); }
private void btnSourceInput1_Click(object sender, EventArgs e) { elanGlobalCacheAdaptor.SendMessage("sendir,4:3,1,40000,1,1,20,179,20,179,20,179,20,179,20,179,20,179,20,179,20,278,20,179,20,179,20,179,20,780" + Environment.NewLine); }
private void btnSystemOff_Click(object sender, EventArgs e) { elanGlobalCacheAdaptor.SendMessage("sendir,4:3,1,40000,1,1,20,184,20,184,20,184,20,184,20,184,20,286,20,286,20,286,20,184,20,184,20,184,20,820" + Environment.NewLine); }
private void btnLightOff_Click(object sender, EventArgs e) { lutronGlobalCacheAdaptor.SendMessage("sdl,14,0,0,S2\x0d"); }
private void btnLightOn_Click(object sender, EventArgs e) { lutronGlobalCacheAdaptor.SendMessage("sdl,14,100,0,S2\x0d"); }
private void btnChannel31_Click(object sender, EventArgs e) { tuneSuiteGlobalCacheAdaptor.SendMessage("\xB8\x4D\xB5\x33\x31\x00\x30\x21\xB8\x0D"); }
private void btnChannel30_Click(object sender, EventArgs e) { tuneSuiteGlobalCacheAdaptor.SendMessage("\xB8\x4D\xB5\x33\x30\x00\x30\x21\xB8\x0D"); }
}
}
public class GlobalCacheAdaptor
{
public Socket _multicastListener;
public string _preferredDeviceID;
public IPAddress _deviceAddress;
public Socket _deviceSocket;
public StreamWriter _deviceWriter;
public bool _isConnected;
public int _port;
public IPAddress _address;
public string _line;
public GlobalCacheAdaptor() { }
public static readonly GlobalCacheAdaptor Instance = new GlobalCacheAdaptor();
public bool IsListening { get { return _multicastListener != null; } }
public GlobalCacheAdaptor ConnectToDevice(IPAddress address, int port)
{
if (_deviceSocket != null) _deviceSocket.Close();
try
{
_port = port;
_address = address;
_deviceSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_deviceSocket.Connect(new IPEndPoint(address, port)); ;
_deviceAddress = address;
var stream = new NetworkStream(_deviceSocket);
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream) { NewLine = "\r", AutoFlush = true };
_deviceWriter = writer;
writer.WriteLine("getdevices");
var readerThread = new Thread(ReaderThreadProc) { IsBackground = true };
readerThread.Start(reader);
_isConnected = true;
return Instance;
}
catch { DisconnectFromDevice(); MessageBox.Show("ConnectToDevice Error."); throw; }
}
public void SendMessage(string message)
{
try
{
var stream = new NetworkStream(_deviceSocket);
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream) { NewLine = "\r", AutoFlush = true };
_deviceWriter = writer;
writer.WriteLine(message);
var readerThread = new Thread(ReaderThreadProc) { IsBackground = true };
readerThread.Start(reader);
}
catch { MessageBox.Show("SendMessage() Error."); }
}
public void DisconnectFromDevice()
{
if (_deviceSocket != null)
{
try { _deviceSocket.Close(); _isConnected = false; }
catch { MessageBox.Show("DisconnectFromDevice Error."); }
_deviceSocket = null;
}
_deviceWriter = null;
_deviceAddress = null;
}
**private void ReaderThreadProc(object state)**
{
var reader = (StreamReader)state;
try
{
while (true)
{
var line = reader.ReadLine();
if (line == null) break;
_line = _line + line + Environment.NewLine;
}
**// Feedback from each piece of equipment is visible here.
// Need to create EventHandler to notify the TextBoxes to update with _line**
}
catch { MessageBox.Show("ReaderThreadProc Error."); }
}
}
From my understanding of the question, you want to do something like this?
You need to know when a GlobalCacheAdapter updates and which one updated in order to update textboxes on a form. My question to you is this - do you actually need to know which updated?
If you declare in your class an event handler like this:
public class GlobalCacheAdaptor
{
public event EventHandler<EventArgs> Updated;
protected virtual void OnUpdated()
{
var handler = Updated;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
private void Foo()
{
// When an update is received, raise Updated event
OnUpdated();
}
}
Then in your form subscribe to Updated for all three GlobalCacheHandler instances
public Form1()
{
elanGlobalCacheAdaptor.Updated += (s,e) =>
{
elanTextBox.Text = elanGlobalCacheAdaptor._line;
}
tuneSuiteGlobalCacheAdaptor.Updated += (s,e) =>
{
tuneSuiteTextBox.Text = tuneSuiteGlobalCacheAdaptor._line;
}
lutronGlobalCacheAdaptor.Updated += (s,e) =>
{
lutronTextBox.Text = lutronGlobalCacheAdaptor._line;
}
}
You should be able to update the correct text box when the appropriate cache handler raises the Updated event.
Finally you may need to handle cross-thread interactions. if so, see this article on MSDN, particularly the part "Thread-Safe Calls to a Windows Forms Control"