I have websocket server and now i need client to test its usage. I am using this clients code:
import org.msgpack.MessagePack;
import org.springframework.web.socket.BinaryMessage;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class TestApp {
public static void main(String[] args) {
try {
// open websocket
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("ws://localhost:8080/websocket"));
// add listener
clientEndPoint.addMessageHandler(new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String message) {
System.out.println(message);
}
});
// send message to websocket
clientEndPoint.sendMessage(new BinaryMessage(...));
// wait 5 seconds for messages from websocket
Thread.sleep(5000);
} catch (InterruptedException ex) {
System.err.println("InterruptedException exception: " + ex.getMessage());
} catch (URISyntaxException ex) {
System.err.println("URISyntaxException exception: " + ex.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
}
import org.springframework.web.socket.BinaryMessage;
import java.net.URI;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
#ClientEndpoint
class WebsocketClientEndpoint {
Session userSession = null;
private MessageHandler messageHandler;
public WebsocketClientEndpoint(URI endpointURI) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Callback hook for Connection open events.
*
* #param userSession the userSession which is opened.
*/
#OnOpen
public void onOpen(Session userSession) {
System.out.println("opening websocket");
this.userSession = userSession;
}
/**
* Callback hook for Connection close events.
*
* #param userSession the userSession which is getting closed.
* #param reason the reason for connection close
*/
#OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing websocket");
this.userSession = null;
}
/**
* Callback hook for Message Events. This method will be invoked when a client send a message.
*
* #param message The text message
*/
#OnMessage
public void onMessage(String message) {
if (this.messageHandler != null) {
this.messageHandler.handleMessage(message);
}
}
/**
* register message handler
*
* #param msgHandler
*/
public void addMessageHandler(MessageHandler msgHandler) {
this.messageHandler = msgHandler;
}
/**
* Send a message.
*
* #param message
*/
public void sendMessage(BinaryMessage message) {
this.userSession.getAsyncRemote().sendObject(message);
}
/**
* Message handler.
*
* #author Jiji_Sasidharan
*/
public static interface MessageHandler {
public void handleMessage(String message);
}
}
When i run this client, my sever accepts it, i am using spring and
void afterConnectionEstablished(WebSocketSession session)
method of BinaryWebSocketHandler fires up and everything seems fine, however after this method, the client does not set userSession , it is still null so it always throw nullpointer exception on
this.userSession.getAsyncRemote().sendObject(message);
which is weird cuz server accepts connection. What is causing this problem? Is there a fix for it?
Thanks for help!
package websocket.client;
import java.net.URI;
import javax.websocket.*;
#ClientEndpoint
public class WSClient {
private static Object waitLock = new Object();
#OnMessage
public void onMessage(String message) {
//the new USD rate arrives from the websocket server side.
System.out.println("Received msg: " + message);
}
private static void wait4TerminateSignal() {
synchronized(waitLock) {
try {
waitLock.wait();
} catch (InterruptedException e) {}
}
}
public static void main(String[] args) {
WebSocketContainer container = null; //
Session session = null;
try {
//Tyrus is plugged via ServiceLoader API. See notes above
container = ContainerProvider.getWebSocketContainer();
//WS1 is the context-root of my web.app
//ratesrv is the path given in the ServerEndPoint annotation on server implementation
session = container.connectToServer(WSClient.class, URI.create("ws://localhost:8080/WS1/ratesrv"));
wait4TerminateSignal();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null) {
try {
session.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Related
This application receives & forwards messages from database events to client applications. Messages are immediately delivered when the client browser has a web socket session.
However, when no web socket session exists and a message is sent by the JMSProducer into the Destination "jms/notificationQueue" in QueueSenderSessionBean, the message is immediately consumed in NotificationEndpoint. This is not my intent.
My intent is for the queue to retain the message until the user connects to NotificationEndpoint. If the user is not connected to the NotificationEndpoint, I think there should be no instance of NotificationEndpoint created to receive the message.
How do I delay the JMSConsumer consuming the message from the queue?
Overview - TomEE Plus 8.0.0-M1 project
Application receives notification in a NotificationServlet
HttpServletRequest
String message is put into JMS Queue by QueueSenderSessionBean injected into NotificationServlet
NotificationMessageDrivenBean implements MessageListener to listen to the JMS Queue
An Event annotated with #NotificationServletJMSMessage is fired from NotificationMessageDrivenBean for an Observer in
NotificationEndpoint method onJMSMessage.
NotificationEndpoint uses PushContext which gathers all websocket sessions to deliver the message to the user
In PushContext.send, if any websocket sessions with a user uuid property matching the message user uuid property, the message is
delivered to each websocket session.
My understanding of #ServerEndpoint is that "each new WS session gets its own instance." Notify only specific user(s) through WebSockets, when something is modified in the database
Sources: the above link from https://stackoverflow.com/users/157882/balusc
and https://blogs.oracle.com/theaquarium/integrating-websockets-and-jms-with-cdi-events-in-java-ee-7-v2
WEB-INF/resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<Resource id="jmsConnectionFactory" type="javax.jms.ConnectionFactory">
connectionMaxIdleTime = 15 Minutes
connectionMaxWaitTime = 5 seconds
poolMaxSize = 10
poolMinSize = 0
resourceAdapter = Default JMS Resource Adapter
transactionSupport = xa
</Resource>
</resources>
NotificationServlet.java
import java.io.IOException;
import java.util.UUID;
import javax.annotation.Resource;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.jms.Queue;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/notifications")
public class NotificationServlet extends HttpServlet
{
#Resource(name = "jms/notificationQueue")
private Queue _notificationQueue;
#Inject
private QueueSenderSessionBean _queueSessionSenderBean;
#Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,
IOException
{
try
{
String notificationJson =
extractNotificationJson(request);
if (notificationJson != null)
{
_queueSessionSenderBean.sendMessage(
"notification="
+ notificationJson);
}
}
catch (Exception e)
{
e.printStackTrace();
// handle exception
}
}
public String extractNotificationJson(HttpServletRequest request)
throws IOException
{
if(request.getParameter("notification") != null)
{
String[] notificationString =
request.getParameterValues("notification");
return notificationString[0];
}
return null;
}
}
QueueSenderSessionBean.java
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jms.DeliveryMode;
import javax.jms.JMSConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.Queue;
import javax.jms.TextMessage;
import org.json.JSONObject;
#Named
#LocalBean
#Stateless
public class QueueSenderSessionBean
{
#Resource(mappedName = "jms/notificationQueue")
private Queue _notificationQueue;
#Inject
#JMSConnectionFactory("jmsConnectionFactory")
private JMSContext _jmsContext;
// Static Methods
// Member Methods
public void sendMessage(String message)
{
try
{
JMSProducer messageProducer =
_jmsContext.createProducer();
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
String userProperty = "someValue";
TextMessage textMessage = _jmsContext.createTextMessage(message);
textMessage.setStringProperty("userProperty", userProperty);
messageProducer.send(_notificationQueue, textMessage);
}
catch (JMSException e)
{
e.printStackTrace();
// handle jms exception
}
}
}
Qualifier NotificationServletJMSMessage.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface NotificationServletJMSMessage
{
}
NotificationMessageDrivenBean.java
import javax.ejb.MessageDriven;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jms.Message;
import javax.jms.MessageListener;
#Named
#MessageDriven(mappedName = "jms/notificationQueue")
public class NotificationMessageDrivenBean implements MessageListener
{
#Inject
#NotificationServletJMSMessage
Event<Message> jmsEvent;
#Override
public void onMessage(Message message)
{
jmsEvent.fire(message);
}
}
PushContext.java
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.TextMessage;
import javax.websocket.Session;
#ApplicationScoped
public class PushContext
{
#Inject
private JMSContext _jmsContext;
#Resource(mappedName = "jms/notificationQueue")
private Queue _notificationQueue;
private Map<String, Set<Session>> _sessions;
#PostConstruct
public void init()
{
_sessions = new ConcurrentHashMap<>();
}
public void add(Session session, String userUuid)
{
_sessions.computeIfAbsent(userUuid,
value -> ConcurrentHashMap.newKeySet()).add(session);
}
void remove(Session session)
{
_sessions.values().forEach(value -> value.removeIf(e -> e.equals(session)));
}
public void send(Set<String> userUuids, Message message) throws JMSException
{
String userUuid = message.getStringProperty("userUuid");
userUuids.add(userUuid);
Set<Session> userSessions;
synchronized(_sessions)
{
userSessions = _sessions.entrySet().stream()
.filter(e -> userUuids.contains(e.getKey()))
.flatMap(e -> e.getValue().stream())
.collect(Collectors.toSet());
}
for (Session userSession : userSessions)
{
if (userSession.isOpen())
{
userSession.getAsyncRemote().sendText(((TextMessage) message).getText());
}
}
}
public void removeSession(Session session)
{
String userUuid = (String)session.getUserProperties().get("userUuid");
_sessions.remove(userUuid, session);
}
}
NotificationEndpoint.java
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
#Named
#ServerEndpoint(value="/notificationEndpoint/{tokenId}")
public class NotificationEndpoint
{
private static final Set<Session> SESSIONS =
Collections.synchronizedSet(new HashSet<Session>());
private QueueSenderSessionBean _senderBean;
#Inject
private PushContext _pushContext;
#Inject
public NotificationEndpoint(QueueSenderSessionBean senderBean)
{
_senderBean = senderBean;
}
#OnOpen
public void onOpen(Session session,
EndpointConfig configurator,
#PathParam(value = "tokenId") String userUuidString)
{
session.getUserProperties().put("userUuid", userUuidString);
_pushContext.add(session, userUuidString);
}
#OnMessage
public void onMessage(String message, Session session)
throws IOException
{
System.out.println("Message received: " + message);
_senderBean.sendMessage(message);
}
#OnClose
public void onClose(CloseReason reason, Session session)
{
System.out.println(
"Closing 'notificatioEndpoint due to "
+ reason.getReasonPhrase());
try
{
session.close();
}
catch (IOException e)
{
e.printStackTrace();
}
_pushContext.removeSession(session);
}
#OnError
public void error(Session session, Throwable t)
{
t.printStackTrace();
}
public static void sendToAllClients(String message)
{
synchronized (SESSIONS)
{
for (Session session : SESSIONS)
{
if (session.isOpen())
{
session.getAsyncRemote().sendText(message);
}
}
}
}
public void onJMSMessage(#Observes #NotificationServletJMSMessage Message message)
{
Set<String> userUuids = new HashSet<String>();
try
{
_pushContext.send(userUuids, message);
}
catch (JMSException ex)
{
ex.printStackTrace();
Logger.getLogger(NotificationEndpoint.class.getName()).
log(Level.SEVERE, null, ex);
}
}
}
Thank you,
Ted S
Delayed message delivery accomplished inspired by the solution here.
The solution was using a local queue to hold messages if the user was not connected to the web socket, then when connected, moving messages from the local queue to a remote queue which gets received/consumed immediately using the MessageDrivenBean.
Also, instead of listening for messages from the database (Postgresql) with a Web Servlet, I changed my DB trigger to NOTIFY and started an asynchronous listener using the pgjdbc-ng driver and the Postgresql LISTEN/NOTIFY pattern described here.
NotificationListener.java
#Stateless
public class NotificationListener extends Thread
{
#Inject
private QueueSenderSessionBean _queueSessionSenderBean;
#Override
public void run()
{
listenToNotifications();
}
public void listenToNotifications()
{
PGNotificationListener listener = new PGNotificationListener()
{
public void notification(int processId, String channelName, String payload)
{
System.out.println("Received notification from: "
+ channelName + ", "
+ payload);
_queueSessionSenderBean.sendMessage(payload);
}
};
PGDataSource dataSource = new PGDataSource();
dataSource.setHost("localhost");
dataSource.setDatabase("db");
dataSource.setPort(5432);
dataSource.setUser("user");
dataSource.setPassword("pass");
try(PGConnection connection =
(PGConnection) dataSource.getConnection())
{
Statement statement = connection.createStatement();
statement.execute("LISTEN notifications");
statement.close();
connection.addNotificationListener(listener);
while (true)
{
if (Thread.currentThread().isInterrupted())
{
break;
}
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
}
NotificationStarter.java
#Singleton
#Startup
public class NotificationsStarter
{
#EJB
private NotificationListener _listener;
#PostConstruct
public void startListener()
{
_listener.start();
}
#PreDestroy
public void shutdown()
{
_listener.interrupt();
}
}
PushContext.java
#ApplicationScoped
public class PushContext
{
#Resource(mappedName = "jms/localNotificationQueue")
private Queue _localNotificationQueue;
#Resource(mappedName = "jms/remoteNotificationQueue")
private Queue _remoteNotificationQueue;
private Map<String, Set<Session>> _sessions;
#PostConstruct
public void init()
{
_sessions = new ConcurrentHashMap<>();
}
public void add(Session session, String userUuid)
{
_sessions.computeIfAbsent(userUuid,
value -> ConcurrentHashMap.newKeySet()).add(session);
}
void remove(Session session)
{
_sessions.values().forEach(value -> value.removeIf(e -> e.equals(session)));
}
public void send(Set<String> userUuids, Message message) throws JMSException
{
String userUuid = message.getStringProperty("userUuid");
userUuids.add(userUuid);
Set<Session> userSessions;
synchronized(_sessions)
{
userSessions = _sessions.entrySet().stream()
.filter(e -> userUuids.contains(e.getKey()))
.flatMap(e -> e.getValue().stream())
.collect(Collectors.toSet());
for (Session userSession : userSessions)
{
if (userSession.isOpen())
{
userSession.getAsyncRemote().sendText(((TextMessage) message).getText());
}
}
}
}
public void removeSession(Session session)
{
String userUuid = (String)session.getUserProperties().get("userUuid");
_sessions.remove(userUuid, session);
}
public Boolean userHasWebSocketSession(String userUuid)
{
Boolean sessionOpen = false;
Set<String> userUuids = new HashSet<String>();
userUuids.add(userUuid);
Set<Session> userSessions;
synchronized(_sessions)
{
userSessions = _sessions.entrySet().stream()
.filter(e -> userUuids.contains(e.getKey()))
.flatMap(e -> e.getValue().stream())
.collect(Collectors.toSet());
}
for (Session userSession : userSessions)
{
if (userSession.isOpen())
{
sessionOpen = true;
break;
}
}
return sessionOpen;
}
}
QueueSenderSessionBean.java
#Named
#LocalBean
#Stateless
public class QueueSenderSessionBean
{
#Resource(mappedName = "jms/localNotificationQueue")
private Queue _localNotificationQueue;
#Resource(mappedName = "jms/remoteNotificationQueue")
private Queue _remoteNotificationQueue;
#Inject
#JMSConnectionFactory("jmsConnectionFactory")
private JMSContext _jmsContext;
#Inject
PushContext _pushContext;
public void sendMessage(String message)
{
JMSProducer messageProducer =
_jmsContext.createProducer();
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
try
{
String userProperty = "someValue";
TextMessage textMessage = _jmsContext.createTextMessage(message);
textMessage.setStringProperty("userProperty", userProperty );
Boolean userIsConnected =
_pushContext.userHasWebSocketSession(userUuid);
if (!userIsConnected)
{
messageProducer.send(_localNotificationQueue, textMessage);
}
else
{
messageProducer.send(_remoteNotificationQueue, textMessage);
}
}
catch (JMSException e)
{
e.printStackTrace();
}
}
}
NotificationMessageDrivenBean.java is now listening to only the remote queue
#Named
#MessageDriven(mappedName = "jms/remoteNotificationQueue")
public class NotificationMessageDrivenBean implements MessageListener
{
#Inject
#NotificationServletJMSMessage
Event<Message> jmsEvent;
#Override
public void onMessage(Message message)
{
jmsEvent.fire(message);
}
}
New QueueReceiverSessionBean.java is used to receive/consume messages from the localNotificationQueue and places them in the remoteNotificationQueue whenever the user connects to NotificationEndpoint web socket.
#Named
#LocalBean
#Stateless
public class QueueReceiverSessionBean
{
#Resource(mappedName = "jms/localNotificationQueue")
private Queue _localNotificationQueue;
#Resource(mappedName = "jms/remoteNotificationQueue")
private Queue _remoteNotificationQueue;
#Inject
#JMSConnectionFactory("jmsConnectionFactory")
private JMSContext _jmsContext;
public void receiveQueuedMessages(String userUuidString) throws JMSException
{
Set<String> userUuids =
new HashSet<String>();
userUuids.add(userUuidString);
JMSConsumer messageConsumer =
_jmsContext.createConsumer(_localNotificationQueue,
"userProperty='someValue'",
true);
JMSProducer messageProducer =
_jmsContext.createProducer();
Message localMessage =
messageConsumer.receive(10);
while(localMessage != null)
{
TextMessage textMessage =
_jmsContext.createTextMessage(((TextMessage) localMessage).getText());
textMessage.setStringProperty("userUuid", userUuidString);
messageProducer.send(_remoteNotificationQueue, textMessage);
localMessage.acknowledge();
localMessage =
messageConsumer.receive(10);
}
messageConsumer.close();
}
public void sendMessage(String message)
{
JMSProducer messageProducer =
_jmsContext.createProducer();
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
try
{
if (message.startsWith("notification"))
{
String messageJson = message.substring(message.indexOf("=") + 1);
JSONObject notificationJson =
new JSONObject(messageJson);
String userUuid = notificationJson.getString("receivinguseruuid");
TextMessage textMessage = _jmsContext.createTextMessage(message);
textMessage.setStringProperty("userUuid", userUuid);
messageProducer.send(_remoteNotificationQueue, textMessage);
}
}
catch (JMSException e)
{
e.printStackTrace();
}
}
}
NotificationEndpoint.java
#Named
#ServerEndpoint(value="/notificationEndpoint/{tokenId}")
public class NotificationEndpoint implements Serializable
{
private static final long serialVersionUID = 1L;
private static final Set<Session> SESSIONS =
Collections.synchronizedSet(new HashSet<Session>());
private QueueReceiverSessionBean _senderBean;
#Inject
private PushContext _pushContext;
#Inject
public NotificationEndpoint(QueueReceiverSessionBean senderBean)
{
_senderBean = senderBean;
}
#OnOpen
public void onOpen(Session session,
EndpointConfig configurator,
#PathParam(value = "tokenId") String userUuidString)
{
session.getUserProperties().put("userUuid", userUuidString );
_pushContext.add(session, userUuidString);
try
{
_senderBean.receiveQueuedMessages(userUuidString);
}
catch (JMSException e)
{
e.printStackTrace();
}
}
#OnMessage
public void onMessage(String message, Session session)
throws IOException
{
_senderBean.sendMessage(message);
}
#OnClose
public void onClose(CloseReason reason, Session session)
{
try
{
session.close();
}
catch (IOException e)
{
e.printStackTrace();
}
_pushContext.removeSession(session);
}
#OnError
public void error(Session session, Throwable t)
{
t.printStackTrace();
}
public static void sendToAllClients(String message)
{
synchronized (SESSIONS)
{
for (Session session : SESSIONS)
{
if (session.isOpen())
{
session.getAsyncRemote().sendText(message);
}
}
}
}
public void onJMSMessage(#Observes #NotificationServletJMSMessage Message message)
{
Set<String> userUuids = new HashSet<String>();
try
{
_pushContext.send(userUuids, message);
}
catch (JMSException ex)
{
ex.printStackTrace();
Logger.getLogger(NotificationEndpoint.class.getName()).
log(Level.SEVERE, null, ex);
}
}
}
Note: This code was used in the TomEE 8.0 container. Injecting JMSContext into the EJBs uncovered a bug in TomEE where the container fails to release the JMSConnection resource. Issue has been added to TomEE issues tracker
I have two topics and one broker URL. I need to publish to these two topics using one broker URL.
I did it with one broker URL and one topic. Then I tried to do with two topics and write two subscriber class for each topic but when I run two subscriber classes one will shows connection lost.
Suggest some good examples to do this.
MQTTPublisher.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttDefaultFilePersistence;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
public class MQTTPublisher {
static final String BROKER_URL = "tcp://localhost:1883";// public mosquitto
// server
static final String TOPIC = "iotm/ej";// Change according to your
// application
static final String TOPIC1 = "iotm/stream1";
public static void main(String args[]) {
try {
// Creating new default persistence for mqtt client
MqttClientPersistence persistence = new MqttDefaultFilePersistence(
"/tmp");
// mqtt client with specific url and client id
MqttClient client1 = new MqttClient(BROKER_URL, "Publisher-ID",
persistence);
client.connect();
MqttTopic myTopic = client1.getTopic(TOPIC);
MqttTopic myTopic1 = client1.getTopic(TOPIC1);
String msg = "AMMA!DEVI!dURGA";
System.out.println("Enter the message to publish,Type quit to exit\n");
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
msg = br.readLine();
while (!msg.equals("quit")) {
myTopic.publish(new MqttMessage(msg.getBytes()));
System.out.println("Message published on" + TOPIC);
myTopic1.publish(new MqttMessage(msg.getBytes()));
System.out.println("Message published on" + TOPIC1);
msg = br.readLine();
}
myTopic.publish(new MqttMessage(msg.getBytes()));
myTopic1.publish(new MqttMessage(msg.getBytes()));
// client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
MQTTSubscriber.java
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttDefaultFilePersistence;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
public class MQTTSubscriber {
static final String BROKER_URL = "tcp://localhost:1883";// public
// mosquitto server
static final String TOPIC = "iotm/ej"; // Change according to your
public static void main(String args[]) {
try {
// Creating new default persistence for mqtt client
MqttDefaultFilePersistence persistence = new MqttDefaultFilePersistence(
"/tmp");
// mqtt client with specific url and a random client id
MqttClient client1 = new MqttClient(BROKER_URL, "Subscriber-ID",
persistence);
client1.connect();
System.out.println("Subscribing to topic '" + TOPIC + "' from "
+ client1.getServerURI());
// Subscribing to specific topic
client1.subscribe(TOPIC);
// It will trigger when a new message is arrived
MqttCallback callback = new MqttCallback() {
#Override
public void messageArrived(MqttTopic arg0, MqttMessage arg1)
throws Exception {
System.out.println("Message:"
+ new String(arg1.getPayload()));
}
#Override
public void deliveryComplete(MqttDeliveryToken arg0) {
}
#Override
public void connectionLost(Throwable arg0) {
System.out.println("Connection lost");
}
};
// Continue waiting for messages until the Enter is pressed
client1.setCallback(callback);
/*
* System.out.println("Press <Enter> to exit"); try {
* System.in.read(); } catch (IOException e) { // If we can't read
* we'll just exit }
*/
// client.disconnect();
// System.out.println("Client Disconnected");
} catch (MqttException e) {
e.printStackTrace();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
MQTTSubscriber2.java
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttDefaultFilePersistence;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
public class MQTTSubscriber2 {
static final String BROKER_URL = "tcp://localhost:1883";// public
// mosquitto server
static final String TOPIC = "iotm/stream1";
public static void main(String args[]) {
try {
// Creating new default persistence for mqtt client
MqttDefaultFilePersistence persistence = new MqttDefaultFilePersistence(
"/tmp");
// mqtt client with specific url and a random client id
MqttClient client = new MqttClient(BROKER_URL, "Subscriber-ID",
persistence);
client.connect();
System.out.println("Subscribing to topic '" + TOPIC + "' from "
+ client.getServerURI());
// Subscribing to specific topic
client.subscribe(TOPIC);
// It will trigger when a new message is arrived
MqttCallback callback = new MqttCallback() {
#Override
public void messageArrived(MqttTopic arg0, MqttMessage arg1)
throws Exception {
System.out.println("Message:"
+ new String(arg1.getPayload()));
}
#Override
public void deliveryComplete(MqttDeliveryToken arg0) {
}
#Override
public void connectionLost(Throwable arg0) {
System.out.println("Connection lost");
}
};
// Continue waiting for messages until the Enter is pressed
client.setCallback(callback);
/*
* System.out.println("Press <Enter> to exit"); try {
* System.in.read(); } catch (IOException e) { // If we can't read
* we'll just exit }
*/
// client.disconnect();
// System.out.println("Client Disconnected");
} catch (MqttException e) {
e.printStackTrace();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
If you are running 2 separate instances of the subscriber code then they will both need different client ids. If you run 2 with the same then the first will be disconnected from the broker when the second connects.
I cannot get the client to send a message to another client without going through the server. It is an obligatory school project that should be implemented like that. I would appreciate it if someone could help me.
Server Interface:
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
public interface ChatServerInt extends Remote {
public abstract void register(ChatClientInt inClient) throws RemoteException;
public abstract ChatClientInt[] getClients() throws RemoteException;
public void disconnect(ChatClientInt client) throws RemoteException;
}
Server Implementation:
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ChatServerImp extends UnicastRemoteObject implements ChatServerInt, Runnable {
private ChatClientInt[] clientList;
int counter = 0;
private ArrayList<String> connectedClients;
/**
* List of all registered remote clients.
*/
private List<ChatClientInt> clients = null;
/**
* Construct an instance of the chat server.
*/
public ChatServerImp() throws RemoteException {
// initialise the list of client objects.
clients = new ArrayList<ChatClientInt>();
connectedClients = new ArrayList<String>();
clientList = new ChatClientInt[16];
}
/**
* Register a chat client.
*/
public void register(ChatClientInt inClient) throws RemoteException {
// perform registration.
synchronized(clients)
{
clients.add(inClient);
clientList[counter++] = inClient;
inClient = new ChatClientImp();
for(int i = 0 ; i < clients.size();i++) {
System.out.println(inClient.getName()+ "has joined\n");
}
}
}
/**After registering, each client will request the list of connected users.
* Get a list of chat clients.
*/
public synchronized ChatClientInt[] getClients() throws RemoteException {
// generate and return the list
return clientList;
}
public void disconnect(ChatClientInt client) throws RemoteException {
for(int i = 0; i < clients.size(); i++) {
System.out.println(client.getName() + "" + "has joined \n");
}
clients.remove(client);
}
/**
* Generate a random subset. Based on an implementation of D. Knuth's
* #return
*/
private static <T> List<T> randomSample2(List<T> items, int m) {
Random rnd = new Random();
for(int i=0;i<items.size();i++){
int pos = i + rnd.nextInt(items.size() - i);
T tmp = items.get(pos);
items.set(pos, items.get(i));
items.set(i, tmp);
}
return items.subList(0, m);
}
/**
* Run the server's main thread. The server should periodically
* iterate through all registered clients to find out if they
* are still alive. Any dead clients will be removed from the
* client list.
*/
public void run() {
while(true) {
//System.out.println("waiting for client connection....\n");
// sleep for a while
try {
Thread.sleep(5000);
// iterate through all the clients we know. if we can't communicate with the client
// then eliminate it else if we can communicate with the client then do nothing.
for(int i =0; i < clients.size(); i++) {
try {
if(clients.get(i).getName()==null) {
clients.remove(clients.get(i).getName());
System.out.println("Disconnected clients:\n" + clients.get(i).getName());
}
}
catch (RemoteException e) {e.printStackTrace();}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Start the chat server.
* #param args
*/
public static void main(String[] args) throws Exception {
//ChatServerInt server;
try {
String serverName = "rmi://localhost/ChatServer";
// create an instance of the chat server
//server = (ChatServerImp) new ChatServerImp();
//Launch the registry - saves invoking it manually
java.rmi.registry.LocateRegistry.createRegistry(1099);
// register the instance with the RMIRegistry
Naming.rebind(serverName, new ChatServerImp());
//Naming.rebind(serverName, server);
// create the server thread and start it
//Thread t = new Thread(server).start();
System.out.println("Server running.....\n");
}
catch(RemoteException ex) {
System.out.println("Error binding the server to rmi");
}
}
}
Message Interface:
import java.util.HashSet;
public interface MessageInt {
/**
* Add a chat recipient to the list of receivers
* #param inClient
*/
public abstract void addRecipient(ChatClientInt inClient);
/**
* Get the set of clients that have seen this message
* #return
*/
public abstract HashSet<ChatClientInt> getRecipients();
/**
* Get the message content.
* #return
*/
public abstract String getContent();
/**
* Get an ID for a sender of the message
* #return
*/
public abstract String getSource();
}
Message Implementation:
import java.io.Serializable;
import java.util.HashSet;
public class MessageImp implements MessageInt, Serializable {
/**
*
*/
private static final long serialVersionUID = -2686034785384409672L;
HashSet<ChatClientInt> clientSet = new HashSet<ChatClientInt>();
String messageContent;
String messageSource;
public MessageImp(String inUser , String inMsg) {
messageSource = inUser;
messageContent = inMsg;
}
/**
* Add a chat recipient to the list of receivers
* #param inClient
*/
public void addRecipient(ChatClientInt inClient) {
synchronized(inClient) {
clientSet.add(inClient);
}
}
/**
* Get the set of clients that have seen this message
* #return
*/
public HashSet<ChatClientInt> getRecipients() {
return clientSet;
}
/**
* Get the message content.
* #return
*/
public String getContent() {
return messageContent;
}
/**
* Get an ID for a sender of the message
* #return
*/
public String getSource() {
return messageSource;
}
}
Client Interface:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatClientInt extends Remote {
/**
* Process a newly received message.
*
* #param inMessage
*/
public void processMessage(MessageInt inMessage)throws RemoteException;
/**
* Returns the name of the client.
*/
public String getName() throws RemoteException;
public boolean sendMessage(MessageInt inMessage) throws RemoteException;
}
Client Implementation:
import java.io.Serializable;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
public class ChatClientImp extends UnicastRemoteObject implements ChatClientInt, Runnable {
/**
*
*/
private static final long serialVersionUID = 74130345076834009L;
private ArrayList <String> eventHistory = new ArrayList<String>();
private HashSet<ChatClientInt> clientSet = new HashSet<ChatClientInt>();
private List<ChatClientInt> clients;// = new ArrayList<ChatClientInt>();
ChatClientInt[] listFromServer = new ChatClientInt[4];
String clientName;
String strMessage;
MessageInt messageObj;
ChatServerInt serverObj;
public ChatClientImp() throws RemoteException {
super();
clients = new ArrayList<ChatClientInt>();
}
public void processMessage(MessageInt inMessage) throws RemoteException {
System.out.println("message:" + inMessage.getRecipients().toString() + inMessage.getSource() + inMessage.getContent() + "\n");
}
public String getName() throws RemoteException {
return clientName;
}
public synchronized boolean sendMessage(MessageInt inMessage) throws RemoteException {
boolean success = false;
for(int i = 0; i < clients.size(); i++) {
clients.get(i).processMessage(inMessage);
inMessage.addRecipient(clients.get(i));
success = true;
}
return success;
}
public void displayMessage(String displayName, String displayMsg) {
Iterator<ChatClientInt> it = clientSet.iterator();
while(it.hasNext()) {
System.out.println(displayName + displayMsg + "\n");
}
}
public void run() {
Scanner scanner = new Scanner(System.in);
String userName = "";
try {
this.serverObj =(ChatServerInt) new ChatServerImp();
} catch (RemoteException e) {
e.printStackTrace();
}
// Keep requesting until a name is submitted that is not already used.
// checking for the existence of a name and adding the name
// is done while locking the set of names.
System.out.println("Please Enter a username\n");
while(true) {
userName = scanner.nextLine();
if(userName==null) {
return;
}
clientName = userName;
try {
serverObj.register(ChatClientImp.this);
listFromServer = serverObj.getClients();
clientSet.add(this);
} catch (RemoteException e) {
e.printStackTrace();
}
System.out.println("Hi" + " " + clientName + " " + "enter your message\n");
String msg = scanner.nextLine();
if(msg.equals("exit")) {
try {
serverObj.disconnect(this);
System.exit(0);
}
catch (RemoteException e) {
e.printStackTrace();
}
}//end if
if((listFromServer.length) > 1) {
System.out.println("list from client is" + " " + listFromServer.length + "going to try to send message.....\n");
try {
this.messageObj = new MessageImp(userName, msg);
boolean result = this.sendMessage(messageObj);
if(result) {
System.out.print("sending result is:" + result + "\n");
} else {
System.out.println("sending was not successful\n");
}
} catch (RemoteException e1) {
System.out.println("Error tryiing to send message from the Run()\n");
}
} else {
System.out.println("There is no one else logged on\n");
}
}
}
public static void main(String[] args) throws RemoteException {
String serverUrl= "rmi://localhost/ChatServer";
try {
ChatServerInt server = (ChatServerInt)Naming.lookup(serverUrl);
Thread thread = new Thread(new ChatClientImp());
thread.start();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
The only way you can do that with RMI is if the clients are also RMI servers and send stubs to each other somehow.
I am trying to implement a TCP Server in Java using nio.
Its simply using the Selector's select method to get the ready keys. And then processing those keys if they are acceptable, readable and so. Server is working just fine till im using a single thread. But when im trying to use more threads to process the keys, the server's response gets slowed and eventually stops responding, say after 4-5 requests.
This is all what im doing:(Pseudo)
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey readyKey = keyIterator.next();
if (readyKey.isAcceptable()) {
//A new connection attempt, registering socket channel with selector
} else {
Worker.add( readyKey );
}
Worker is the thread class that performs Input/Output from the channel.
This is the code of my Worker class:
private static List<SelectionKey> keyPool = Collections.synchronizedList(new LinkedList());
public static void add(SelectionKey key) {
synchronized (keyPool) {
keyPool.add(key);
keyPool.notifyAll();
}
}
public void run() {
while ( true ) {
SelectionKey myKey = null;
synchronized (keyPool) {
try {
while (keyPool.isEmpty()) {
keyPool.wait();
}
} catch (InterruptedException ex) {
}
myKey = keyPool.remove(0);
keyPool.notifyAll();
}
if (myKey != null && myKey.isValid() ) {
if (myKey.isReadable()) {
//Performing reading
} else if (myKey.isWritable()) {
//performing writing
myKey.cancel();
}
}
}
My basic idea is to add the key to the keyPool from which various threads can get a key, one at a time.
My BaseServer class itself is running as a thread. It is creating 10 Worker threads before the event loop to begin. I also tried to increase the priority of BaseServer thread, so that it gets more chance to accept the acceptable keys. Still, to it stops responding after approx 8 requests. Please help, were I am going wrong. Thanks in advance. :)
Third, you aren't removing anything from the selected-key set. You must do that every time around the loop, e.g. by calling keyIterator.remove() after you call next().
You need to read the NIO Tutorials.
First of all, you should not really be using wait() and notify() calls anymore since there exist good Standard Java (1.5+) wrapper classes in java.util.concurrent, such as BlockingQueue.
Second, it's suggested to do IO in the selecting thread itself, not in the worker threads. The worker threads should just queue up reads/and writes to the selector thread(s).
This page explains it pretty good and even provides working code samples of a simple TCP/IP server: http://rox-xmlrpc.sourceforge.net/niotut/
Sorry, I don't yet have time to look at your specific example.
Try using xsocket library. It saved me a lot of time reading on forums.
Download: http://xsocket.org/
Tutorial: http://xsocket.sourceforge.net/core/tutorial/V2/TutorialCore.htm
Server Code:
import org.xsocket.connection.*;
/**
*
* #author wsserver
*/
public class XServer {
protected static IServer server;
public static void main(String[] args) {
try {
server = new Server(9905, new XServerHandler());
server.start();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
protected static void shutdownServer(){
try{
server.close();
}catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
Server Handler:
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.*;
import org.xsocket.*;
import org.xsocket.connection.*;
public class XServerHandler implements IConnectHandler, IDisconnectHandler, IDataHandler {
private Set<ConnectedClients> sessions = Collections.synchronizedSet(new HashSet<ConnectedClients>());
Charset charset = Charset.forName("ISO-8859-1");
CharsetEncoder encoder = charset.newEncoder();
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer buffer = ByteBuffer.allocate(1024);
#Override
public boolean onConnect(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, MaxReadSizeExceededException {
try {
synchronized (sessions) {
sessions.add(new ConnectedClients(inbc, inbc.getRemoteAddress()));
}
System.out.println("onConnect"+" IP:"+inbc.getRemoteAddress().getHostAddress()+" Port:"+inbc.getRemotePort());
} catch (Exception ex) {
System.out.println("onConnect: " + ex.getMessage());
}
return true;
}
#Override
public boolean onDisconnect(INonBlockingConnection inbc) throws IOException {
try {
synchronized (sessions) {
sessions.remove(inbc);
}
System.out.println("onDisconnect");
} catch (Exception ex) {
System.out.println("onDisconnect: " + ex.getMessage());
}
return true;
}
#Override
public boolean onData(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException {
inbc.read(buffer);
buffer.flip();
String request = decoder.decode(buffer).toString();
System.out.println("request:"+request);
buffer.clear();
return true;
}
}
Connected Clients:
import java.net.InetAddress;
import org.xsocket.connection.INonBlockingConnection;
/**
*
* #author wsserver
*/
public class ConnectedClients {
private INonBlockingConnection inbc;
private InetAddress address;
//CONSTRUCTOR
public ConnectedClients(INonBlockingConnection inbc, InetAddress address) {
this.inbc = inbc;
this.address = address;
}
//GETERS AND SETTERS
public INonBlockingConnection getInbc() {
return inbc;
}
public void setInbc(INonBlockingConnection inbc) {
this.inbc = inbc;
}
public InetAddress getAddress() {
return address;
}
public void setAddress(InetAddress address) {
this.address = address;
}
}
Client Code:
import java.net.InetAddress;
import org.xsocket.connection.INonBlockingConnection;
import org.xsocket.connection.NonBlockingConnection;
/**
*
* #author wsserver
*/
public class XClient {
protected static INonBlockingConnection inbc;
public static void main(String[] args) {
try {
inbc = new NonBlockingConnection(InetAddress.getByName("localhost"), 9905, new XClientHandler());
while(true){
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Client Handler:
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import org.xsocket.MaxReadSizeExceededException;
import org.xsocket.connection.IConnectExceptionHandler;
import org.xsocket.connection.IConnectHandler;
import org.xsocket.connection.IDataHandler;
import org.xsocket.connection.IDisconnectHandler;
import org.xsocket.connection.INonBlockingConnection;
/**
*
* #author wsserver
*/
public class XClientHandler implements IConnectHandler, IDataHandler,IDisconnectHandler, IConnectExceptionHandler {
Charset charset = Charset.forName("ISO-8859-1");
CharsetEncoder encoder = charset.newEncoder();
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer buffer = ByteBuffer.allocate(1024);
#Override
public boolean onConnect(INonBlockingConnection nbc) throws IOException {
System.out.println("Connected to server");
nbc.write("hello server\r\n");
return true;
}
#Override
public boolean onConnectException(INonBlockingConnection nbc, IOException ioe) throws IOException {
System.out.println("On connect exception:"+ioe.getMessage());
return true;
}
#Override
public boolean onDisconnect(INonBlockingConnection nbc) throws IOException {
System.out.println("Dissconected from server");
return true;
}
#Override
public boolean onData(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException {
inbc.read(buffer);
buffer.flip();
String request = decoder.decode(buffer).toString();
System.out.println(request);
buffer.clear();
return true;
}
}
I spent a lot of time reading on forums about this, i hope i can help u with my code.
I am new to Apache MINA kindly guide me how to read from IoSession. I have stored a POJO in it.
public static EchoUDPServerDiscoveryObjectResponseProperties echoProperties
session.write(echoProperties);
Custom Client:
package client;
import java.net.InetSocketAddress;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.util.logging.Level;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.example.udp.client.MemMonClient;
import org.apache.mina.transport.socket.nio.NioDatagramConnector;
/**
*
* #author az
*/
public class CustomClient extends IoHandlerAdapter{
private IoSession session;
private IoConnector connector;
private ConnectFuture connFuture;
public CustomClient() throws InterruptedException{
connector = new NioDatagramConnector();
connector.setHandler(this);
connFuture = connector.connect(new InetSocketAddress("192.168.3.22",6502));
connFuture.addListener(new IoFutureListener<ConnectFuture>() {
public void operationComplete(ConnectFuture future) {
if (future.isConnected()) {
session = future.getSession();
try {
try {
sendData();
// connFuture.await();
} catch (CharacterCodingException ex) {
java.util.logging.Logger.getLogger(MemMonClient.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
private void sendData() throws InterruptedException, CharacterCodingException {
IoBuffer buffer = IoBuffer.allocate(8);
buffer.setAutoExpand(true);
buffer.putString("any", Charset.forName("UTF-8").newEncoder());
buffer.flip();
session.write(buffer);
}
#Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
cause.printStackTrace();
}
#Override
public void messageReceived(IoSession session, Object message)
throws Exception {
connFuture.getSession().getConfig().setUseReadOperation(true);
ReadFuture r = connFuture.getSession().read();
connFuture.await();
connFuture.getSession().getConfig().setUseReadOperation(true);
Object obj = r.getMessage();
System.out.println("r.getMessage(); "+obj);
IoBuffer buffer = IoBuffer.allocate(2048);
buffer.setAutoExpand(true);
Object objReceived = buffer.getObject();
System.out.println(objReceived.toString());
System.out.println("reveived Session recv...");
}
#Override
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("Message sent...");
}
#Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
#Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
}
#Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
#Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session opened...");
}
public static void main (String are[]){
try{
new CustomClient();
}catch(Exception ex){ex.printStackTrace();}
}
}
POJO Java
package pojo;
import java.io.Serializable;
/**
*
* #author az
*/
public class kojo implements Serializable{
private String name = "null";
private String address = "null";
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the address
*/
public String getAddress() {
return address;
}
/**
* #param address the address to set
*/
public void setAddress(String address) {
this.address = address;
}
}
Custom Server Java
package server;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
/**
*
* #author az
*/
public class CustomServer {
public CustomServer(){
try {
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
acceptor.setHandler(new ServerHandler(this));
//DefaultIoFilterChainBuilder filter = acceptor.getFilterChain();
DatagramSessionConfig dcfg = acceptor.getSessionConfig();
dcfg.setReuseAddress(true);
acceptor.bind(new InetSocketAddress(6501));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void receiveUpdate(){
}
public static void main(String are[]){
new CustomServer();
}
}
Server Handler
package server;
import java.nio.charset.Charset;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
/**
*
* #author az
*/
public class ServerHandler extends IoHandlerAdapter {
private CustomServer server;
public ServerHandler(CustomServer server) {
this.server = server;
}
#Override
public void messageReceived(IoSession session, Object message)
throws Exception {
if (message instanceof IoBuffer) {
//decode POJO and send to client
IoBuffer buffer = (IoBuffer) message;
System.out.println(buffer.getString(Charset.forName("UTF-8").newDecoder()));
buffer.setAutoExpand(true);
buffer.putObject(new pojo.POJO());
buffer.flip();
session.write(buffer);
System.out.print("Object Attached and Sent");
}
}
#Override
public void messageSent(IoSession session, Object message) {
System.out.println("Message sent");
}
#Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
#Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
}
#Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
#Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session Opened...");
}
}