2015-09-04 72 views
1

我正在尝试使用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"})); 
     } 



    }]); 

在运行方法:

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无法看到通知。

请帮助我!

回答

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

+0

对不起已故的答复,但我要感谢你,$范围$ evalAsync效果很好,在情况下,如果我们面对的问题。像“$ scope.apply()已经在进行中”,我已经使用$ scope。$ evalAsync在我的逻辑之一,它运作良好,但仍然面临问题集成气氛与dropwizard。 –