AtmosphereHandler - 聊天:当我发送消息时,我得到“未定义”

时间:2015-12-01 08:27:23

标签: atmosphere

我在使用这个聊天示例时遇到了问题: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>

enter image description here

的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>');
}});

1 个答案:

答案 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;
}
}