如何从服务器向客户端发送消息?

10

我要实现类似Facebook通知和StackOverflow的网站通知功能,即在有人对我们的问题写评论/回答等时通知我们。请注意,用户将使用我的应用作为网站而不是移动应用程序。

我发现了以下的答案,它获取结果,但我需要推送结果而不是获取。

根据建议,我在我的实体类中创建了一个简单的方法并添加了@PostPersist,但它没有起作用,所以根据这个答案,我添加了persistence.xml文件来定义监听器,但在session.save(user)后,aftersave方法没有被触发。

User.java

@Entity
public class User{
  .....
  @PostPersist
    public void aftersave(){
        System.err.println("*****this is post persist method****");
    }
}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->

<property name="hibernate.ejb.event.pre-insert"  value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.pre-update"  value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.pre-delete"  value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.post-insert" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.post-update" value="my.hibernate.events.listeners.Listener" />
<property name="hibernate.ejb.event.post-delete" value="my.hibernate.events.listeners.Listener" />

pom.xml

 <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.2.1.Final</version>
            <type>jar</type>
        </dependency>

1
根据你使用的数据库引擎而定,大多数不支持更改监听器,以下是来自Postgres文档的示例。你可能可以使用hibernate监听器,在你想要关注的实体上使用@PostPersist应该可以解决问题。 - Boris the Spider
@BoristheSpider的问题已更新。 - J888
6个回答

13

听起来需要使用WebSockets。它是Java EE 7的一部分,因此Glassfish应该是最先支持它的AS之一。

要拦截DB访问,可以使用@PostUpdate@PostPersist。这里有一个相关的question

有很多方法可以进行所谓的服务器推送,以通知已连接的客户端:

编辑:在Java世界中,有几个框架可以实现服务器推送(反向ajax)。如果您熟悉GWT,我建议使用Errai。另一个选择是Atmospere。 Atmospere的缺点是它需要与您的常规应用程序服务器及Web应用程序一起运行的独立进程。我是一年前在玩它,所以自那时以来可能已经改变。
总的来说,很难为您提供具体的代码片段,因为它取决于您选择的框架。我熟悉Errai,所以这里是一个例子: 服务器端:
@ApplicationScoped
public class TickerService {

  @Inject
  private Event<Tick> tickEvent;

  private void sendTick() {
    tickEvent.fire(new Tick());
  }
} 

客户端:

@EntryPoint
public class TickerClient {
  public void tickHappened(@Observes Tick tick) {

    // update the UI with the new data
  }
}

使用Errai的其他好处是在服务器和客户端上默认支持CDI,另一个好处是如果支持,可以在底层使用web-sockets并在不支持时回退到其他解决方案。

无论您选择什么,它都应该适合您现有的基础架构和客户端UI框架。


2
技巧并不在于数据库...(因为JPA / Hibernate在这方面提供了清晰的解决方案),而在于如何实现ajax。有一个专门用于此目的的框架称为Atmosphere,值得一试:https://dev59.com/Y2865IYBdhLWcg3wEaUx 它试图考虑客户端限制,尽管我希望在不久的将来WebSockets将是这条路线的唯一明智选择。 - Quaternion

4

MQTT可用于服务器推送和消息广播。

有更详细的信息可以在http://mqtt.org/找到。

======================================

更新日期:2013年7月11日

MQTT是一种发布/订阅、极其简单和轻量级的消息传递协议。如果服务器是发布者,客户端浏览器订阅了服务器发布的主题,那么服务器就可以直接向客户端推送消息。

以下是一些有用的资源:

Mosquitto是一个开源的MQTT服务器。易于安装和配置。

mqtt-client是一个已被证实的强大Java MQTT客户端。


您能提供更多细节吗? - J888

4
使用 Node JSsocket.io 技术。
该技术根据客户端使用的浏览器选择最佳的传输方法。
对于最新的浏览器,它使用Web Sockets;对于其他浏览器,它会优雅地退化到Flash Socket或长轮询。在此处了解更多信息
您需要做的是使用这些技术设置一个服务器。服务器将在特定端口上运行。所有客户端都将侦听该端口,服务器将能够通过该端口向客户端推送数据。

它是一个网站,它在网站上工作吗?还是只在客户端服务器平台上工作? - J888
这项技术仅适用于浏览器。您需要自己创建客户端-服务器平台。所有浏览器都将充当客户端,您需要编写一些代码来构建一个服务器。请访问 socket.io 网站获取示例代码。 - Manu

4

彗星,也称为反向Ajax,是一种Web应用程序模型,其中长时间持有的HTTP请求允许Web服务器向浏览器推送数据,而无需浏览器明确请求。

Comet(又名长连接http,服务器推送)允许服务器缓慢地开始回答浏览器对信息的请求,并按照服务器指定的时间表继续回答。有关Comet的更多信息,请参见以下内容:

DWR 是一个Java库,可以在服务器上使用Java和浏览器中的JavaScript进行交互和调用,尽可能地简单易懂。通过 Reverse Ajax,DWR 允许运行在服务器上的 Java 代码使用客户端API发布更新到任意组的浏览器,实现双向交互 - 浏览器调用服务器和服务器调用浏览器。DWR 支持 Comet、Polling 和 Piggyback(将数据与正常请求一起发送)作为发布到浏览器的方式。

DWR 提供与 Spring、Struts、Guice、Hibernate 等框架的集成。您可以从 这里 阅读更多内容。

其他 Comet 和 Reverse AJAX 框架:


2

每30秒或根据需要从服务器检查更新。

window.setInterval(function(){
  /// call your function here
 //Make AJAX call
 //Update Respective HTML Contact i,e, DIV

}, 30000);

2

但是在session.save(user)之后,aftersave方法没有被触发。

  • @PostPersist是JPA回调函数。
  • session.save()是非JPA的Hibernate专有方法。JPA使用entityManager.persist()
  • 您正在使用不兼容的功能。

那么对于Hibernate来说,有什么解决方案呢? - J888
首先,我总是选择标准的方法,如果有的话。在这种情况下,使用EntityManager和@PostPersist,参考http://docs.jboss.org/hibernate/devguide/en-US/html/的JPA。其次,我查看了Hibernate专有文档,但没有找到“callback”或“post”的提及,但似乎可以重写Envers监听器以通知您事件。虽然不完全干净,但应该可以工作,*如果这是您想要的*:http://docs.jboss.org/hibernate/devguide/en-US/html/ch15.html。 - Glen Best
将JPA和Hibernate结合使用是否高效? - J888
不完全是低效的,更加复杂。除非你有充分的理由,否则我肯定不会混合使用这两种模式。有些人会尽可能地使用JPA,然后在需要额外功能时回退到“原始Hibernate”。但这样做有以下问题:(a)复杂(b)相当罕见,因为JPA非常丰富。当然,仍有许多“传统”用户仅使用原始Hibernate,他们还没有切换到JPA——但是,他们错过了JPA添加的新功能。 :) - Glen Best

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接