我实现了一个JMS客户端,它应该在JMS消息到达时更新浏览器。不幸的是,大约50%的消息丢失了,从未到达。真的很奇怪。可能是什么原因?
这里我发布了部分代码。我根据weblogic的html5 websocket示例创建了客户端,我有版本12.1.2。我在java和javascript方面都没有错误。控制台打印来自Bean的接收消息:每两秒钟打印一次,但我每4秒钟才收到一次,甚至更少。那是为什么?
package com.packtpub.techbuzz.jms;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.jms.JMSException;
import javax.jms.MessageListener;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.websocket.ClosingMessage;
import weblogic.websocket.WebSocketAdapter;
import weblogic.websocket.WebSocketConnection;
import weblogic.websocket.WebSocketListener;
import weblogic.websocket.annotation.WebSocket;
@WebSocket(timeout = -1, pathPatterns = "/counter.ws")
public class SocketMediator extends WebSocketAdapter implements WebSocketListener, MessageListener {
private static SocketMediator sm;
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY = "jms/myConnectionFactory";
private static final String RETURN_QUEUE = "jms/TestJMSReturnQueue";
private static final String QUEUE = "jms/myTestQueue";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private QueueSender qsender;
private javax.jms.Queue queueReturn;
private javax.jms.Queue queue;
private boolean isConnected;
public static SocketMediator getSm() {
return sm;
}
public SocketMediator() {
super();
sm = this;
isConnected = false;
try {
InitialContext ctx = new InitialContext();
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (javax.jms.Queue) ctx.lookup(QUEUE);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qsender = qsession.createSender(queue);
qcon.start();
isConnected = true;
int counter = 0;
// Use the ThreadScheduledExecutor to invoke a runnable at a later time
// which posts some data into the queue
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
try {
try {
TextMessage textMessage = qsession.createTextMessage("Shit happens");
qsender.send(textMessage);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception ex) {
}
}
}, 2, 1, TimeUnit.SECONDS);
} catch (JMSException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
@Override
public void onOpen(WebSocketConnection webSocketConnection) {
System.out.println("New connection was created from a client " + webSocketConnection.getRemoteAddress());
super.onOpen(webSocketConnection);
}
@Override
public void onMessage(WebSocketConnection connection, String payload) {
// Sends message from the browser back to the client.
System.out.println("Does this ever actually fire?");
}
@Override
public void onClose(WebSocketConnection webSocketConnection, ClosingMessage closingMessage) {
super.onClose(webSocketConnection, closingMessage);
System.out.println("Connection was closed from a client " + webSocketConnection.getRemoteAddress());
}
@Override
public void onError(WebSocketConnection webSocketConnection, Throwable throwable) {
super.onError(webSocketConnection, throwable);
System.out.println("Something went seriously wrong with client " + webSocketConnection.getRemoteAddress());
}
// Subscription for return messages
@Override
public void onMessage(javax.jms.Message msg) {
final String msgText;
try {
if (msg instanceof TextMessage) {
msgText = ((TextMessage) msg).getText();
} else {
msgText = msg.toString();
}
System.out.println("Received message from bean: "+msgText);
for(final WebSocketConnection conn : getWebSocketContext().getWebSocketConnections()){
Executors.newSingleThreadScheduledExecutor().schedule(
new Runnable() {
@Override
public void run() {
try {
conn.send(msgText);
} catch (Exception ex) {
}
}
}, 1, TimeUnit.SECONDS);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}