1

私はSpring-MVCアプリケーションに取り組んでおり、SOのユーザーのおかげで、すでにCometdチャット機能が機能しています。アプリケーションにあるもう 1 つの機能は通知ですが、Facebook のように、発生したらすぐにリアルタイム通知を統合したいと考えています。

基本的には、新しい通知が作成されるたびにデータベースに保存され、バックエンドからのその情報は、各ユーザーの一意のチャネルでログインしているユーザーの通知に渡される必要があります。

通知をチャット クラスにルーティングするには、いくつかの作業が必要になるため、このアプローチが機能するかどうかを知りたいと思います。ChatServiceImpl クラスのインターフェースも持っていないことに注意してください。それは大丈夫ですか?十分な話ですが、コードは次のとおりです。

ChatServiceImpl :

@Named
@Singleton
@Service
public class ChatServiceImpl {
    @Inject
    private BayeuxServer bayeux;

    @Session
    private ServerSession serverSession;


    public void sendNotification(Notification notification,int id
// And then I send notification here like below, by extracting information from the notification object.

 ServerChannel serverChannel = bayeux.createChannelIfAbsent("/person/notification/" + id).getReference();
        serverChannel.setPersistent(true);
        serverChannel.publish(serverSession, output);
        }
    }

上記のクラスにはインターフェースがないため、次のようにメソッドを使用する予定でした:

@Service
@Transactional
public class GroupCanvasServiceImpl implements GroupCanvasService{
    private ChatServiceImpl chatService;

   public void someMethod(){
   chatService.sendNotification(notification, id);
}
}

BayeuxInitializer :

@Component
public class BayeuxInitializer implements DestructionAwareBeanPostProcessor, ServletContextAware
{
    private BayeuxServer bayeuxServer;
    private ServerAnnotationProcessor processor;

    @Inject
    private void setBayeuxServer(BayeuxServer bayeuxServer)
    {
        this.bayeuxServer = bayeuxServer;
    }

    @PostConstruct
    private void init()
    {

        this.processor = new ServerAnnotationProcessor(bayeuxServer);
    }

    @PreDestroy
    private void destroy()
    {
        System.out.println("Bayeux in PreDestroy");
    }

    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException
    {
        processor.processDependencies(bean);
        processor.processConfigurations(bean);
        processor.processCallbacks(bean);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException
    {
        return bean;
    }

    public void postProcessBeforeDestruction(Object bean, String name) throws BeansException
    {
        processor.deprocessCallbacks(bean);
    }

    @Bean(initMethod = "start", destroyMethod = "stop")
    public BayeuxServer bayeuxServer()
    {
        return new BayeuxServerImpl();
    }

    public void setServletContext(ServletContext servletContext)
    {
        servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
    }
}

この方法でよろしければ教えてください。どうもありがとう。

4

1 に答える 1

2

注釈は、@Listenerリモート クライアントから受信したメッセージを処理するメソッド用です。

サーバーからクライアントへのメッセージのみを送信する必要がある場合は、メソッドに で注釈を付ける必要はありません。パブリッシュ@Listener先の を取得しServerChannel、それを使用してメッセージをパブリッシュするだけで十分です。

特定のケースでは、複数のサブスクライバーのチャネルでメッセージをブロードキャストする必要はないようですが、idパラメーターで識別される特定のクライアントにメッセージを送信するだけで済みます。

その場合は、次の方法でピアツーピア メッセージングを使用する方がよいでしょう。

public void sendNotification(Notification notification, int id)
{
    ServerSession remoteClient = retrieveSessionFromId(id);
    remoteClient.deliver(serverSession, "/person/notification", notification);
}

このソリューションには、はるかに少ないチャネルを作成するという利点があります ( ごとにチャネルは必要ありませんid)。

さらに良いことに、/person/notificationチャネル (ブロードキャスト チャネル) を などのサービス チャネルに置き換えることができます/service/notification。このように、通知の伝達に使用されるチャネルがピアツーピア通信用であることは明らかです (サービス チャネルはメッセージのブロードキャストに使用できないため)。

retrieveSessionFromId()メソッドは、ユーザーのログイン時にマップする必要があるものです。たとえば、CometD 認証に関するドキュメントを参照してください

于 2015-05-20T09:31:25.037 に答える