I am having trouble with this example of chat: https://github.com/Atmosphere/atmosphere/wiki/Getting-Started-with-AtmosphereHandler,-WebSocket-and-Long-Polling
In this simple example is used an implemetation of AtmosphereHandler to create a chat application.
How you could see from the pic below, i don't see what i have wrote but only an "undefined" message. Why? Where is the error?
Thank you a lot.
web.xml:
<display-name>AtmoChat</display-name>
<description>Atmosphere Chat</description>
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<!-- limit classpath scanning to speed up starting, not mandatory -->
<init-param>
<param-name>org.atmosphere.cpr.packages</param-name>
<param-value>org.atmosphere.samples</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.interceptor.HeartbeatInterceptor.clientHeartbeatFrequencyInSeconds</param-name>
<param-value>10</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<url-pattern>/chat/*</url-pattern>
</servlet-mapping>
application.js:
$(function () {
"use strict";
var header = $('#header');
var content = $('#content');
var input = $('#input');
var status = $('#status');
var myName = false;
var author = null;
var logged = false;
var socket = atmosphere;
var subSocket;
var transport = 'websocket';
// We are now ready to cut the request
var request = { url: 'http://myLink/' + 'chat',
contentType : "application/json",
logLevel : 'debug',
transport : transport ,
trackMessageLength : true,
reconnectInterval : 5000 };
request.onOpen = function(response) {
content.html($('<p>', { text: 'Atmosphere connected using ' + response.transport }));
input.removeAttr('disabled').focus();
status.text('Choose name:');
transport = response.transport;
// Carry the UUID. This is required if you want to call subscribe(request) again.
request.uuid = response.request.uuid;
};
request.onClientTimeout = function(r) {
content.html($('<p>', { text: 'Client closed the connection after a timeout. Reconnecting in ' + request.reconnectInterval }));
subSocket.push(atmosphere.util.stringifyJSON({ author: author, message: 'is inactive and closed the connection. Will reconnect in ' + request.reconnectInterval }));
input.attr('disabled', 'disabled');
setTimeout(function (){
subSocket = socket.subscribe(request);
}, request.reconnectInterval);
};
request.onReopen = function(response) {
input.removeAttr('disabled').focus();
content.html($('<p>', { text: 'Atmosphere re-connected using ' + response.transport }));
};
// For demonstration of how you can customize the fallbackTransport using the onTransportFailure function
request.onTransportFailure = function(errorMsg, request) {
atmosphere.util.info(errorMsg);
request.fallbackTransport = "long-polling";
header.html($('<h3>', { text: 'Atmosphere Chat. Default transport is WebSocket, fallback is ' + request.fallbackTransport }));
};
request.onMessage = function (response) {
var message = response.responseBody;
try {
var json = atmosphere.util.parseJSON(message);
} catch (e) {
console.log('This doesn\'t look like a valid JSON: ', message);
return;
}
input.removeAttr('disabled').focus();
if (!logged && myName) {
logged = true;
status.text(myName + ': ').css('color', 'blue');
} else {
var me = json.author == author;
var date = typeof(json.time) == 'string' ? parseInt(json.time) : json.time;
addMessage(json.author, json.message, me ? 'blue' : 'black', new Date(date));
}
};
request.onClose = function(response) {
content.html($('<p>', { text: 'Server closed the connection after a timeout' }));
if (subSocket) {
subSocket.push(atmosphere.util.stringifyJSON({ author: author, message: 'disconnecting' }));
}
input.attr('disabled', 'disabled');
};
request.onError = function(response) {
content.html($('<p>', { text: 'Sorry, but there\'s some problem with your '
+ 'socket or the server is down' }));
logged = false;
};
request.onReconnect = function(request, response) {
content.html($('<p>', { text: 'Connection lost, trying to reconnect. Trying to reconnect ' + request.reconnectInterval}));
input.attr('disabled', 'disabled');
};
subSocket = socket.subscribe(request);
input.keydown(function(e) {
if (e.keyCode === 13) {
var msg = $(this).val();
// First message is always the author's name
if (author == null) {
author = msg;
}
subSocket.push(atmosphere.util.stringifyJSON({ author: author, message: msg }));
$(this).val('');
input.attr('disabled', 'disabled');
if (myName === false) {
myName = msg;
}
}
});
function addMessage(author, message, color, datetime) {
content.append('<p><span style="color:' + color + '">' + author + '</span> @ ' +
+ (datetime.getHours() < 10 ? '0' + datetime.getHours() : datetime.getHours()) + ':'
+ (datetime.getMinutes() < 10 ? '0' + datetime.getMinutes() : datetime.getMinutes())
+ ': ' + message + '</p>');
}});
Ok. For now, I don't see any trouble about your "onMessage" method in your javascript code. Your javascript code is based on simple chat room from documentation of atmosphere-js. So, your code is correct.
I need to see your Java code for how you send object message to client app. I need also to see your class Java representing the model object message to send.
Maybe, the value of message attribute from object model class is null or empty. That's why you have "undefined" value in your message field.
Your model java class must be like :
public class ChatMessage {
private String message;
private String author;
private long time = System.currentTimeMillis();
public ChatMessage(){
this("","");
}
public ChatMessage(String author, String message) {
this.author = author;
this.message = message;
this.time = new Date().getTime();
}
public String getMessage(){
return message;
}
public String getAuthor(){
return author;
}
public void setAuthor(String author){
this.author = author;
}
public void setMessage(String message){
this.message = message;
}
public long getTime(){
return time;
}
public void setTime(long time){
this.time = time;
}
}
Here's an class Java to manage a chat application :
import java.io.IOException;
import org.atmosphere.config.service.Disconnect;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Message;
import org.atmosphere.config.service.PathParam;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Simple annotated class that demonstrate the power of Atmosphere. This class
* supports all transports, support message length guarantee, heart beat,
* message cache thanks to the @ManagedService.
*/
@ManagedService(path = "/chatRoom/{room_id}")
public final class ChatRoom {
private static final Logger logger = LoggerFactory.getLogger(ChatRoom.class);
@PathParam("room_id")
private String chatRoomId;
/**
* Invoked when the connection as been fully established and suspended, e.g
* ready for receiving messages.
*
* @param r
* the atmosphere resource
* @return
*/
@Ready
public final void onReady(final AtmosphereResource r) {
logger.info("Browser {} connected.", r.uuid());
}
/**
* Invoked when the client disconnect or when an unexpected closing of the
* underlying connection happens.
*
* @param event
* the event
* @throws IOException
*/
@Disconnect
public final void onDisconnect(final AtmosphereResourceEvent event) throws IOException {
if (event.isCancelled()) {
logger.info("Browser {} unexpectedly disconnected", event.getResource().uuid());
}
else if (event.isClosedByClient()) {
logger.info("Browser {} closed the connection", event.getResource().uuid());
}
}
/**
* Simple annotated class that demonstrate how
* {@link org.atmosphere.config.managed.Encoder} and {@link org.atmosphere.config.managed.Decoder
* can be used.
*
* @param message an instance of {@link ChatMessage }
* @return the chat message
*/
@Message(encoders = { ChatMessageEncoderDecoder.class }, decoders = { ChatMessageEncoderDecoder.class })
public final ChatMessage onMessage(final ChatMessage message) {
logger.info("{} just send {}", message.getAuthor(), message.getMessage());
return message;
}
}