I'm trying some scenarios with JMS and JBoss 4.2.2 and I have few problems with it.
I have a Queue
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=notificationQueue">
<attribute name="JNDIName">jms.queue.testQueue</attribute>
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
<depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
<attribute name="SecurityConf">
<security>
<role name="testUser" read="true" write="true" />
</security>
</attribute>
</mbean>
and
<invoker-proxy-binding>
<name>message-driven-bean</name>
<invoker-mbean>default</invoker-mbean>
<proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
<proxy-factory-config>
<JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
<ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
<CreateJBossMQDestination>true</CreateJBossMQDestination>
<MinimumSize>1</MinimumSize>
<MaximumSize>15</MaximumSize>
<MaxMessages>16</MaxMessages>
<MDBConfig>
<ReconnectIntervalSec>10</ReconnectIntervalSec>
<DLQConfig>
<DestinationQueue>queue/DLQ</DestinationQueue>
<MaxTimesRedelivered>3</MaxTimesRedelivered>
<TimeToLive>0</TimeToLive>
<DLQUser>jbossmquser</DLQUser>
<DLQPassword>letmein</DLQPassword>
</DLQConfig>
</MDBConfig>
</proxy-factory-config>
</invoker-proxy-binding>
To test redelivery I wrote MessageListener
import java.util.*;
import javax.jms.*;
import javax.naming.*;
public class NotifyQueueMessageListener {
public static void main(String[] args) throws NamingException, JMSException {
Hashtable<String, String> contextProperties = new Hashtable<String, String>();
contextProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
contextProperties.put(Context.PROVIDER_URL, "jnp://localhost:7099");
InitialContext initContext = new InitialContext(contextProperties);
Queue queue = (Queue) initContext.lookup("jms.queue.testQueue");
QueueConnection queueConnection = null;
try {
QueueConnectionFactory connFactory = (QueueConnectionFactory) initContext.lookup("ConnectionFactory");
queueConnection = connFactory.createQueueConnection("jbossmquser", "letmein");
Session queueSession = queueConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
queueConnection.setExceptionListener(new MyExceptionListener());
MessageConsumer consumer = queueSession.createConsumer(queue);
MyMessageListener messageListener = new MyMessageListener();
consumer.setMessageListener(messageListener);
queueConnection.start();
Object o = new Object();
synchronized (o) {
o.wait();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
System.out.println("closing connection");
if (queueConnection != null) {
queueConnection.close();
}
}
}
static class MyMessageListener implements MessageListener {
#Override
public void onMessage(Message message) {
if (message instanceof ObjectMessage) {
ObjectMessage om = (ObjectMessage) message;
try {
System.out.printf("MyMessageListener.onMessage( %s ), %s\n\n", om, om.getObject());
boolean throwException = om.getBooleanProperty("throw");
if (throwException) {
System.out.println("throwing exception");
throw new NullPointerException("just for testing");
}
message.acknowledge();
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}
}
}
static class MyExceptionListener implements ExceptionListener {
#Override
public void onException(JMSException jmse) {
jmse.printStackTrace();
}
}
}
and MessageSender
import java.text.*;
import java.util.*;
import javax.jms.*;
import javax.naming.*;
public class MessageSender {
public static void main(String[] args) throws NamingException, JMSException {
Hashtable<String, String> contextProperties = new Hashtable<String, String>();
contextProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
contextProperties.put(Context.PROVIDER_URL, "jnp://localhost:7099");
InitialContext initContext = new InitialContext(contextProperties);
Queue queue = (Queue) initContext.lookup("notificationQueue");
QueueConnection queueConnection = null;
try {
QueueConnectionFactory connFactory = (QueueConnectionFactory) initContext.lookup("ConnectionFactory");
queueConnection = connFactory.createQueueConnection("jbossmquser", "letmein");
// QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// QueueSession queueSession = queueConnection.createQueueSession(true, Session.SESSION_TRANSACTED);
QueueSession queueSession = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
// QueueSession queueSession = queueConnection.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE);
QueueSender sender = queueSession.createSender(queue);
ObjectMessage message = queueSession.createObjectMessage();
message.setBooleanProperty("throw", true); // to throw exception in listener
message.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
message.setIntProperty("JMS_JBOSS_REDELIVERY_LIMIT", 3);
sender.send(message);
} finally {
System.out.println("closing connection");
if (queueConnection != null) {
queueConnection.close();
}
}
}
}
Expected behavior
Because I'm throwing Exception in onMessage() I expect that message will tried again several times (<MaxTimesRedelivered>3</MaxTimesRedelivered>) and after that it will be moved to DLQ, but it's not.
What I tried
I tried all acknowledge modes (AUTO, CLIENT, DUPS_OK) together with commiting, acknowledging but nothing worked, even message wasn't sent again.
I have no idea what's wrong. There is nothing relevant in JBoss logs.
When I try to stop and run again MesageListener I'm getting:
MyMessageListener.onMessage( org.jboss.mq.SpyObjectMessage {
Header {
jmsDestination : QUEUE.notificationQueue
jmsDeliveryMode : 2
jmsExpiration : 0
jmsPriority : 4
jmsMessageID : ID:13-13577584629501
jmsTimeStamp : 1357758462950
jmsCorrelationID: 20130109200742
jmsReplyTo : null
jmsType : null
jmsRedelivered : true
jmsProperties : {JMSXDeliveryCount=7, throw=true, JMS_JBOSS_REDELIVERY_LIMIT=3, JMS_JBOSS_REDELIVERY_COUNT=6}
jmsPropReadWrite: false
msgReadOnly : true
producerClientId: ID:13
}
} ), my message (2013-01-09 20:07:42)
MyMessageListener.onMessage( org.jboss.mq.SpyObjectMessage {
Header {
jmsDestination : QUEUE.notificationQueue
jmsDeliveryMode : 2
jmsExpiration : 0
jmsPriority : 4
jmsMessageID : ID:15-13577584942741
jmsTimeStamp : 1357758494274
jmsCorrelationID: 20130109200814
jmsReplyTo : null
jmsType : null
jmsRedelivered : true
jmsProperties : {JMSXDeliveryCount=6, throw=true, JMS_JBOSS_REDELIVERY_LIMIT=3, JMS_JBOSS_REDELIVERY_COUNT=5}
jmsPropReadWrite: false
msgReadOnly : true
producerClientId: ID:15
}
} ), my message (2013-01-09 20:08:14)
MyMessageListener.onMessage( org.jboss.mq.SpyObjectMessage {
Header {
jmsDestination : QUEUE.notificationQueue
jmsDeliveryMode : 2
jmsExpiration : 0
jmsPriority : 4
jmsMessageID : ID:20-13577586971991
jmsTimeStamp : 1357758697199
jmsCorrelationID: 20130109201137
jmsReplyTo : null
jmsType : null
jmsRedelivered : true
jmsProperties : {JMSXDeliveryCount=2, throw=true, JMS_JBOSS_REDELIVERY_LIMIT=3, JMS_JBOSS_REDELIVERY_COUNT=1}
jmsPropReadWrite: false
msgReadOnly : true
producerClientId: ID:20
}
} ), my message (2013-01-09 20:11:37)
MyMessageListener.onMessage( org.jboss.mq.SpyObjectMessage {
Header {
jmsDestination : QUEUE.notificationQueue
jmsDeliveryMode : 2
jmsExpiration : 0
jmsPriority : 4
jmsMessageID : ID:21-13577587683201
jmsTimeStamp : 1357758768320
jmsCorrelationID: 20130109201248
jmsReplyTo : null
jmsType : null
jmsRedelivered : true
jmsProperties : {JMSXDeliveryCount=2, throw=true, JMS_JBOSS_REDELIVERY_LIMIT=3, JMS_JBOSS_REDELIVERY_COUNT=1}
jmsPropReadWrite: false
msgReadOnly : true
producerClientId: ID:21
}
} ), my message (2013-01-09 20:12:48)
as you can see I tried also JMS_JBOSS_REDELIVERY_LIMIT.
Any idea?
I found very helpful post
https://community.jboss.org/wiki/ThrowingExceptionsFromAnMDB
that reads:
What type of Exceptions should an MDB throw?
The quick answer is none.
When I used transaction and createQueueSession(true, Session.SESSION_TRANSACTED) it worked just fine (redelivery and also DLQ).
Related
I am trying to handle the exception at the listener
#KafkaListener(id = PropertiesUtil.ID,
topics = "#{'${kafka.consumer.topic}'}",
groupId = "${kafka.consumer.group.id.config}",
containerFactory = "containerFactory",
errorHandler = "errorHandler")
public void receiveEvents(#Payload List<ConsumerRecord<String, String>> recordList,
Acknowledgment acknowledgment) {
try {
log.info("Consuming the batch of size {} from kafka topic {}", consumerRecordList.size(),
consumerRecordList.get(0).topic());
processEvent(consumerRecordList);
incrementOffset(acknowledgment);
} catch (Exception exception) {
throwOrHandleExceptions(exception, recordList, acknowledgment);
.........
}
}
The Kafka container config:
#Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>>
containerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConcurrency(this.numberOfConsumers);
factory.getContainerProperties().setAckOnError(false);
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
factory.setConsumerFactory(getConsumerFactory());
factory.setBatchListener(true);
return factory;
}
}
the listener error handler impl
#Bean
public ConsumerAwareListenerErrorHandler errorHandler() {
return (m, e, c) -> {
MessageHeaders headers = m.getHeaders();
List<String> topics = headers.get(KafkaHeaders.RECEIVED_TOPIC, List.class);
List<Integer> partitions = headers.get(KafkaHeaders.RECEIVED_PARTITION_ID, List.class);
List<Long> offsets = headers.get(KafkaHeaders.OFFSET, List.class);
Map<TopicPartition, Long> offsetsToReset = new HashMap<>();
for (int i = 0; i < topics.size(); i++) {
int index = i;
offsetsToReset.compute(new TopicPartition(topics.get(i), partitions.get(i)),
(k, v) -> v == null ? offsets.get(index) : Math.min(v, offsets.get(index)));
}
...
};
}
when i try to run the same without the batching processing then i am able to fetch the partition,topic and offset values but when i enable batch processing and try to test it then i am getting only two values inside the headers i.e id and timestamp and other values are not set. Am i missing anything here??
What version are you using? I just tested it with Boot 2.2.4 (SK 2.3.5) and it works fine...
#SpringBootApplication
public class So60152179Application {
public static void main(String[] args) {
SpringApplication.run(So60152179Application.class, args);
}
#KafkaListener(id = "so60152179", topics = "so60152179", errorHandler = "eh")
public void listen(List<String> in) {
throw new RuntimeException("foo");
}
#Bean
public ConsumerAwareListenerErrorHandler eh() {
return (m, e, c) -> {
System.out.println(m);
return null;
};
}
#Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> {
template.send("so60152179", "foo");
};
}
#Bean
public NewTopic topic() {
return TopicBuilder.name("so60152179").partitions(1).replicas(1).build();
}
}
spring.kafka.listener.type=batch
spring.kafka.consumer.auto-offset-reset=earliest
GenericMessage [payload=[foo], headers={kafka_offset=[0], kafka_nativeHeaders=[RecordHeaders(headers = [], isReadOnly = false)], kafka_consumer=org.apache.kafka.clients.consumer.KafkaConsumer#2f2e787f, kafka_timestampType=[CREATE_TIME], kafka_receivedMessageKey=[null], kafka_receivedPartitionId=[0], kafka_receivedTopic=[so60152179], kafka_receivedTimestamp=[1581351585253], kafka_groupId=so60152179}]
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 {
}
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;
}
}
}
I am trying to write an asynchronous socket Server/Client, but I keep getting the following error:
Unable to read data from the transport connection: A blocking operation was interrupted
by a call to WSACancelBlockingCall.
Inner Exception: System.Net.Sockets.SocketException (0x80004005): A blocking operation
was interrupted by a call to WSACancelBlockingCall
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size,
SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
This exception it thrown in my SockerServer class at the following line:
BytesRead = ClientStream.Read(MessageBuffer, 0, BufferSize);
This only occurs when the Client attempts to disconnect from the server - they appear to disconnect fine and then I get this exception.
Here is the codez:
MessageHandler
There is a single instance of this class in the Client and one for each of the clients in the server. This is used to wrap the NetworkStream for each client so that messages can be written to it.
public class MessageHandler
{
private readonly ASCIIEncoding ByteEncoder = new ASCIIEncoding();
private readonly NetworkStream ClientStream;
public MessageHandler(NetworkStream Stream)
{
this.ClientStream = Stream;
}
public void Send(byte[] Message)
{
ClientStream.Write(Message, 0, Message.Length);
ClientStream.Flush();
}
public void Send(string Message)
{
byte[] MessageBytes = ByteEncoder.GetBytes(Message);
ClientStream.Write(MessageBytes, 0, MessageBytes.Length);
ClientStream.Flush();
}
}
MessageHandlerEventArgs
public class MessageHandlerEventArgs : EventArgs
{
public readonly MessageHandler SocketMessage;
public MessageHandlerEventArgs(MessageHandler Messages)
{
this.SocketMessage = Messages;
}
}
SocketHandler (Base class for SocketServer & SocketClient)
public abstract class SocketHandler
{
protected const int DefaultPort = 3000;
protected const int BufferSize = 4096;
protected readonly Action<byte[]> MessageAction;
public SocketHandler(Action<byte[]> MessageAction)
{
this.MessageAction = MessageAction;
ClientConnected += OnClientConnected;
ClientDisconnected += OnClientDisconnected;
}
protected void HandleConnection(IAsyncResult ar)
{
TcpClient Client = (TcpClient)ar.AsyncState;
ThreadPool.QueueUserWorkItem((x) => HandleConnection(Client));
}
protected void HandleConnection(TcpClient NetworkClient)
{
try
{
using (NetworkStream ClientStream = NetworkClient.GetStream())
{
MessageHandler Messages = new MessageHandler(ClientStream);
DoClientConnected(new MessageHandlerEventArgs(Messages));
byte[] MessageBuffer = new byte[BufferSize];
int BytesRead;
while (true)
{
BytesRead = 0;
BytesRead = ClientStream.Read(MessageBuffer, 0, BufferSize);
if (BytesRead == 0)
{
DoClientDisconnected(new MessageHandlerEventArgs(Messages));
break;
}
else
{
MessageAction.Invoke(MessageBuffer.ToArray());
}
}
NetworkClient.Close();
}
}
catch (Exception ex)
{
Logger.ExceptionLog.AddEntry(ex, "SocketHandler.HandleConnection");
}
}
protected abstract void OnClientConnected(object sender, MessageHandlerEventArgs e);
protected abstract void OnClientDisconnected(object sender, MessageHandlerEventArgs e);
public event EventHandler<MessageHandlerEventArgs> ClientConnected;
protected void DoClientConnected(MessageHandlerEventArgs args)
{
if (ClientConnected != null)
{
ClientConnected(this, args);
}
}
public event EventHandler<MessageHandlerEventArgs> ClientDisconnected;
protected void DoClientDisconnected(MessageHandlerEventArgs args)
{
if (ClientDisconnected != null)
{
OnClientDisconnected(this, args);
}
}
public event EventHandler StatusChanged;
protected void DoStatusChanged()
{
if (StatusChanged != null)
{
StatusChanged(this, EventArgs.Empty);
}
}
}
Socket Server
public class SocketServer : SocketHandler
{
private static List<MessageHandler> CurrentClients = new List<MessageHandler>();
private ServerStatus _Status;
public ServerStatus Status
{
get { return _Status; }
private set
{
_Status = value;
DoStatusChanged();
}
}
private readonly TcpListener NetworkServer;
public SocketServer(Action<byte[]> MessageAction)
: base(MessageAction)
{
NetworkServer = new TcpListener(IPAddress.Any, DefaultPort);
}
public void Start()
{
try
{
if (Status == ServerStatus.Stopped)
{
ThreadPool.QueueUserWorkItem((x) => ListenForClient());
Status = ServerStatus.Started;
}
}
catch (Exception ex)
{
Logger.ExceptionLog.AddEntry(ex, "SocketServer.Start");
}
}
public void Stop()
{
try
{
if (Status != ServerStatus.Stopped)
{
Status = ServerStatus.Stopped;
NetworkServer.Stop();
}
}
catch (Exception ex)
{
Logger.ExceptionLog.AddEntry(ex, "SocketServer.Stop");
}
}
private void ListenForClient()
{
try
{
Status = ServerStatus.WaitingClient;
NetworkServer.Start();
while (Status != ServerStatus.Stopped)
{
if (!NetworkServer.Pending())
{
Thread.Sleep(100);
continue;
}
else
{
TcpClient NetworkClient = NetworkServer.AcceptTcpClient();
ThreadPool.QueueUserWorkItem((x) => HandleConnection(NetworkClient));
Status = ServerStatus.Connected;
}
}
}
catch (Exception ex)
{
Logger.ExceptionLog.AddEntry(ex, "SocketServer.ListenForClient");
}
}
protected override void OnClientConnected(object sender, MessageHandlerEventArgs e)
{
CurrentClients.Add(e.SocketMessage);
}
protected override void OnClientDisconnected(object sender, MessageHandlerEventArgs e)
{
CurrentClients.Remove(e.SocketMessage);
Status = (CurrentClients.Count == 0)
? ServerStatus.WaitingClient
: ServerStatus.Connected;
}
}
SocketClient
public class SocketClient : SocketHandler
{
private ClientStatus _Status;
public ClientStatus Status
{
get { return _Status; }
set
{
_Status = value;
DoStatusChanged();
}
}
private TcpClient NetworkClient;
public MessageHandler Messages;
public SocketClient(Action<byte[]> MessageAction)
: base(MessageAction)
{
NetworkClient = new TcpClient();
}
public void Connect(IPAddress ServerAddress, int ServerPort)
{
try
{
if (Status == ClientStatus.Disconnected)
{
Status = ClientStatus.Connecting;
NetworkClient.Connect(ServerAddress, ServerPort);
ThreadPool.QueueUserWorkItem((x) => HandleConnection(NetworkClient));
}
}
catch (Exception ex)
{
Logger.ExceptionLog.AddEntry(ex, "SocketClient.Connect");
}
}
public void Disconnect()
{
try
{
if (Status != ClientStatus.Disconnected)
{
Status = ClientStatus.Disconnecting;
NetworkClient.Close();
Status = ClientStatus.Disconnected;
}
}
catch (Exception ex)
{
Logger.ExceptionLog.AddEntry(ex, "SocketClient.Disconnect");
}
}
protected override void OnClientConnected(object sender, MessageHandlerEventArgs e)
{
Messages = e.SocketMessage;
Status = ClientStatus.Connected;
}
protected override void OnClientDisconnected(object sender, MessageHandlerEventArgs e)
{
Messages = null;
Status = ClientStatus.Disconnected;
}
}
Do not code like that. Using threads/thread pool is just wrong. The Socket/TcpClient has asynchronous methods which should be used
I've created a framework which you can use. It takes care of all processing for you. all you need to do is to handle the incoming/outgoing data.
http://blog.gauffin.org/2012/05/griffin-networking-a-somewhat-performant-networking-library-for-net/
I'm new to JMS and I'm studying the following example
public class SendRecvClient
{
static CountDown done = new CountDown(1);
QueueConnection conn;
QueueSession session;
Queue que;
public static class ExListener
implements MessageListener
{
public void onMessage(Message msg)
{
done.release();
TextMessage tm = (TextMessage) msg;
try {
System.out.println("onMessage, recv text=" + tm.getText());
} catch(Throwable t) {
t.printStackTrace();
}
}
}
public void setupPTP()
throws JMSException,
NamingException
{
InitialContext iniCtx = new InitialContext();
Object tmp = iniCtx.lookup("ConnectionFactory");
QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
conn = qcf.createQueueConnection();
que = (Queue) iniCtx.lookup("queue/testQueue");
session = conn.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
conn.start();
}
public void sendRecvAsync(String text)
throws JMSException,
NamingException
{
System.out.println("Begin sendRecvAsync");
// Setup the PTP connection, session
setupPTP();
// Set the async listener
QueueReceiver recv = session.createReceiver(que);
recv.setMessageListener(new ExListener());
// Send a text msg
QueueSender send = session.createSender(que);
TextMessage tm = session.createTextMessage(text);
send.send(tm);
System.out.println("sendRecvAsync, sent text=" + tm.getText());
send.close();
System.out.println("End sendRecvAsync");
}
public void stop()
throws JMSException
{
conn.stop();
session.close();
conn.close();
}
public static void main(String args[])
throws Exception
{
SendRecvClient client = new SendRecvClient();
client.sendRecvAsync("A text msg");
client.done.acquire();
client.stop();
System.exit(0);
}
}
I ran this in JBoss and it gave the following exception
Begin sendRecvAsync
Exception in thread "main" javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at se.cambio.jms.SendRecvClient.setupPTP(SendRecvClient.java:53)
at se.cambio.jms.SendRecvClient.sendRecvAsync(SendRecvClient.java:68)
at se.cambio.jms.SendRecvClient.main(SendRecvClient.java:95)
I think this is an error with JNDI name, but I couldn't find which xml file to edit in JBOSS to over come this problem. Please some one help me.