我正在尝试使用Atmosphere和dropwizard进行推送通知。 在这里我想做什么: 假设用户1想要向用户2发送通知,所以当用户1点击发送通知按钮时,通知应显示给用户2.
NotificationResource.java
package resource;
import java.io.IOException;
import javax.inject.Inject;
import javax.ws.rs.Path;
import org.atmosphere.cache.UUIDBroadcasterCache;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
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.atmosphere.cpr.AtmosphereResourceFactory;
import org.atmosphere.cpr.AtmosphereResponse;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.cpr.MetaBroadcaster;
import org.atmosphere.handler.OnMessage;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.BroadcastOnPostAtmosphereInterceptor;
import org.atmosphere.interceptor.HeartbeatInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import representation.Data;
import utility.JacksonDecoder;
import utility.JacksonEncoder;
import com.fasterxml.jackson.databind.ObjectMapper;
@ManagedService(path = "/{user}")
public class NotificationResource {
private final Logger logger = LoggerFactory.getLogger(NotificationResource.class);
@PathParam("user")
private String chatroomName;
@Inject
private BroadcasterFactory factory;
@Inject
private AtmosphereResourceFactory resourceFactory;
@Inject
private MetaBroadcaster metaBroadcaster;
@Ready
public void onReady(final AtmosphereResource r) {
logger.info("Browser {} connected.", r.uuid());
}
@Disconnect
public void onDisconnect(AtmosphereResourceEvent event) {
if (event.isCancelled()) {
logger.info("Browser {} unexpectedly disconnected", event.getResource().uuid());
} else if (event.isClosedByClient()) {
logger.info("Browser {} closed the connection", event.getResource().uuid());
}
}
/* @Message(encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class})
public Data onMessage(Data message) throws IOException {
logger.info("{} just send {}",message.getAuthor(), message.getMessage());
return message;
}*/
@Message(encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class})
public void onPrivateMessage(Data message,AtmosphereResource r) throws IOException {
System.out.println(r.uuid()+"______________");
// Retrieve the original AtmosphereResource
System.out.println("In private notification+++++++++================");
factory.lookup("/chat/*").broadcast(message.getAuthor()+"Someone Pinged you", r);
}
}
clientjs
mode.controller('notificationController',['$scope','atmosphereService','$cookies',function($scope,atmosphereService,$cookies){
$scope.model = {
transport: 'websocket',
messages: []
};
var socket;
user=angular.fromJson($cookies.get('user_details_object'))['user_name'];
pingUrl='/chat/'+user
var request = {
url:pingUrl ,
contentType: 'application/json',
logLevel: 'debug',
transport: 'websocket',
trackMessageLength: true,
reconnectInterval: 5000,
enableXDR: true,
timeout: 60000
};
request.onOpen = function(response){
$scope.model.transport = response.transport;
$scope.model.connected = true;
$scope.model.content = 'Atmosphere connected using ' + response.transport;
};
request.onClientTimeout = function(response){
$scope.model.content = 'Client closed the connection after a timeout. Reconnecting in ' + request.reconnectInterval;
$scope.model.connected = false;
socket.push(atmosphere.util.stringifyJSON({ author: "author", message: 'is inactive and closed the connection. Will reconnect in ' + request.reconnectInterval }));
setTimeout(function(){
socket = atmosphereService.subscribe(request);
}, request.reconnectInterval);
};
request.onReopen = function(response){
$scope.model.connected = true;
$scope.model.content = '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';
$scope.model.header = 'Atmosphere Chat. Default transport is WebSocket, fallback is ' + request.fallbackTransport;
};
request.onMessage = function(response){
var responseText = response.responseBody;
try{
var message = atmosphere.util.parseJSON(responseText);
var date = typeof(message.time) === 'string' ? parseInt(message.time) : message.time;
$scope.model.messages.push({author: message.author, date: new Date(date), text: message.message});
}catch(e){
console.error("Error parsing JSON: ", responseText);
throw e;
}
};
request.onClose = function(response){
$scope.model.connected = false;
$scope.model.content = 'Server closed the connection after a timeout';
socket.push(atmosphere.util.stringifyJSON({ author: $scope.model.name, message: 'disconnecting' }));
};
request.onError = function(response){
$scope.model.content = "Sorry, but there's some problem with your socket or the server is down";
$scope.model.logged = false;
};
request.onReconnect = function(request, response){
$scope.model.content = 'Connection lost. Trying to reconnect ' + request.reconnectInterval;
$scope.model.connected = false;
};
socket = atmosphereService.subscribe(request);
$scope.notifyClient=function(name){
console.log("=="+name);
socket.push(atmosphere.util.stringifyJSON({author:name, message: "hello"}));
}
}]);
在run方法中:
AtmosphereServlet servlet = new AtmosphereServlet();
servlet.framework().addInitParameter("com.sun.jersey.config.property.packages", "dk.cooldev.chatroom.resources.websocket");
servlet.framework().addInitParameter(ApplicationConfig.WEBSOCKET_CONTENT_TYPE, "application/json");
servlet.framework().addInitParameter(ApplicationConfig.WEBSOCKET_SUPPORT, "true");
ServletRegistration.Dynamic servletHolder = environment.servlets().addServlet("Chat", servlet);
servletHolder.addMapping("/chat/*");
我可以连接websocket,当我点击"发送通知"来自用户1的按钮,它调用$ scope.notifyClient但问题用户2无法看到通知。
请帮助我!!
答案 0 :(得分:1)
request.onMessage
是角度摘要周期外部的事件。您需要将事件逻辑包装在$scope.$evalAsync
:
$scope.$evalAsync(function () {
$scope.model.messages.push({author: message.author, date: new Date(date), text: message.message});
});
请参阅:http://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm