我在使用这个聊天示例时遇到了问题:https://github.com/Atmosphere/atmosphere/wiki/Getting-Started-with-AtmosphereHandler,-WebSocket-and-Long-Polling
在这个简单的例子中使用了AtmosphereHandler的实现来创建聊天应用程序。
你如何从下面的图片中看到,我看不出我写的是什么,只是一个“未定义”的消息。为什么?错误在哪里?
非常感谢你。
的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>');
}});
答案 0 :(得分:1)
确定。现在,我没有看到你的javascript代码中的“onMessage”方法有任何问题。您的javascript代码基于来自atmosphere-js文档的简单聊天室。所以,你的代码是正确的。
我需要查看您的Java代码,了解如何将对象消息发送到客户端应用程序。我还需要看到你的Java类代表要发送的模型对象消息。
也许,来自对象模型类的message属性的值为null或为空。这就是您在消息字段中有“未定义”值的原因。
您的模型java类必须如下:
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;
}
}
这是一个用于管理聊天应用程序的Java类:
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;
}
}