vendredi 10 avril 2015

Spring MVC : Combining listener and sender in Cometd


  • I am working on a Spring-MVC application in which I would like to use Cometd chat mechanism for GroupChat. I checked out the examples, and the StockPriceEmitter and Client-Side server hello are good, but there is one essential thing I cannot find in the tutorials is how to combine these examples.

    • Tutorial Link : Link

    • If someone knows how the examples work, they can skip this paragraph. So, basically how Client-Side server hello works is a hello message is sent on a service channel '/service/hello', and in server side, it is printed. StockPriceEmitter works opposite, it creates some values in backend and sends them over to the front-end on specific channel.

    • My problem is I would like to broadcast the message which is received from the client to all the channel subscribers, in essence, combining the above two examples.




Code :


Client-side server hello :



@Service
public class MessageReceiver {

// When I am getting data from client, I want to read the channel-id(123 here, group stays constant), rather then specifying which one it is.
@Listener("/group/123")
public void processClientMessage(ServerSession serverSession, ServerMessage serverMessage){
// Here, instead of printing, I would like to send data to the class which emits the message to subscribed, the major problem.
System.out.println("Recieved message is "+serverMessage.getData()+" Session id is "+serverSession.getId());
}
}


MessageSenderClass.java :



public class MessageSender implements Runnable{

public final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final List<String> symbols = new ArrayList<String>();
private final Map<String, Float> values = new HashMap<>();
private final List<Listener> listeners = new CopyOnWriteArrayList<>();


// Here instead of adding the values in constructor, I want to call method in this class to notify whenever there is a new message.
public MessageSender()
{
symbols.addAll(Arrays.asList("ORCL", "MSFT", "GOOG", "YHOO", "FB"));
values.put("ORCL", 29.94f);
values.put("MSFT", 27.10f);
values.put("GOOG", 655.37f);
values.put("YHOO", 17.82f);
values.put("FB", 21.33f);
}
public List<Listener> getListeners()
{
return listeners;
}
public void start()
{
run();
}

public void stop()
{
scheduler.shutdownNow();
}

public void run()
{
Random random = new Random();

List<Update> updates = new ArrayList<Update>();

// Randomly choose how many stocks to update
int howMany = random.nextInt(symbols.size()) + 1;
for (int i = 0; i < howMany; ++i)
{
// Randomly choose which one to update
int which = random.nextInt(symbols.size());
String symbol = symbols.get(which);
float oldValue = values.get(symbol);

// Randomly choose how much to update
boolean sign = random.nextBoolean();
float howMuch = random.nextFloat();
float newValue = oldValue + (sign ? howMuch : -howMuch);

// Store the new value
values.put(symbol, newValue);

updates.add(new Update(symbol, oldValue, newValue));
}

// Notify the listeners
for (Listener listener : listeners)
{
listener.onUpdates(updates);
}

// Randomly choose how long for the next update
// We use a max delay of 1 second to simulate a high rate of updates
long howLong = random.nextInt(1000);
scheduler.schedule(this, howLong, TimeUnit.MILLISECONDS);
}

public static class Update
{
private final String symbol;
private final float oldValue;
private final float newValue;

public Update(String symbol, float oldValue, float newValue)
{
this.symbol = symbol;
this.oldValue = oldValue;
this.newValue = newValue;
}

public String getSymbol()
{
return symbol;
}

public float getOldValue()
{
return oldValue;
}

public float getNewValue()
{
return newValue;
}
}

public interface Listener extends EventListener
{
void onUpdates(List<Update> updates);
}
}


I hope I was clear. If there is any doubts, please leave a comment. I am actively editing the code to suit the message Model I want, but this is one of the technical problem of combination I have to iron out before making this thing work. Any help would be nice. Thanks a lot. :-)


Aucun commentaire:

Enregistrer un commentaire