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

时间:2022-06-16 00:16:51

I am going to implement something similar to Facebook notification and this website (*'s notification which is notifying us if anyone write a comment/answer etc for our question). Please note users are going to use my application as a website not mobile application.

我将实现类似于Facebook通知和本网站的内容(*的通知,如果有人为我们的问题写了评论/答案等,则会通知我们)。请注意,用户将使用我的应用程序作为网站而不是移动应用程序。

I came across following answer which fetch the results, but I need to push the results not fetch.

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

Based on suggestions I have created a simple method in my entity class and added the @PostPersist to it but it has not worked so based on this answer I added the persistence.xml file to define the listeners but after session.save(user) the aftersave method does not get triggered.

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

User.java

User.java

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

persistence.xml

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

的pom.xml

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

6 个解决方案

#1


13  

Sounds like a task for WebSockets. It is part of Java EE 7 so the Glassfish should be one of the first AS that will support it.

听起来像WebSockets的任务。它是Java EE 7的一部分,因此Glassfish应该是第一个支持它的AS之一。

For intercepting the DB access you can use @PostUpdate and @PostPersist. Here is related question.

要拦截数据库访问,您可以使用@PostUpdate和@PostPersist。这是相关的问题。

There are many ways to do the so called Server Push for notifying the connected clients:

有许多方法可以执行所谓的服务器推送以通知连接的客户端:

  • polling (the link you've provided in the question ("Are we there yet? Are we there yet? ..."))
  • 民意调查(你在问题中提供的链接(“我们还有吗?我们还在吗?......”))
  • long polling (smarter way of polling - long-lived HTTP technique using keepalive messages)
  • 长轮询(更智能的轮询方式 - 使用keepalive消息的长期HTTP技术)
  • WebSockets (JSR 356)
  • WebSockets(JSR 356)
  • piggy-backing
  • 捎带
  • SPDY(wiki)
  • SPDY(维基)
  • Server-Sent Events (related answer, wiki)
  • 服务器发送的事件(相关答案,维基)

EDIT: In the Java world, there are couple of frameworks where server push (reverse ajax) is implemented out-of-the box. If you are familiar with GWT, I would suggest Errai. Other alternative is the Atmospere. The downside of the Atmospere is the fact that it requires standalone running process next to your regular application server with your web app. I was playing with it a year ago so this may have been changed since then.

编辑:在Java世界中,有几个框架,其中服务器推送(反向ajax)是开箱即用的。如果您熟悉GWT,我会建议Errai。另一种选择是Atmospere。 Atmospere的缺点是它需要使用您的Web应用程序在常规应用程序服务器旁边的独立运行过程。一年前我正在玩它,所以从那时起可能已经改变了。

In general, it is hard to provide you with a concrete piece of code, because it depends on the framework you will choose. I am familiar with Errai so here is an example in it:

通常,很难为您提供具体的代码,因为它取决于您将选择的框架。我熟悉Errai,所以这里有一个例子:

Server Side:

服务器端:

@ApplicationScoped
public class TickerService {

  @Inject
  private Event<Tick> tickEvent;

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

Client Side:

客户端:

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

    // update the UI with the new data
  }
}

Other benefits of using the Errai is having the CDI on the server and on the client out-of-the-box, another thing that is nice is using the web-sockets under the covers if it is supported and falling back to other solutions otherwise.

使用Errai的其他好处是将CDI放在服务器上和开箱即用的客户端上,另一件好事就是使用支持下的网络套接字,如果支持则退回到其他解决方案,否则。

Whatever you choose, it should fit to your existing infrastructure and to your client side UI framework.

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

#2


4  

mqtt can be used for server pushing and message broadcasting.

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

There are more detail information in http://mqtt.org/.

http://mqtt.org/中有更多详细信息。

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

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

Updated: Jul 11, 2013

更新时间:2013年7月11日

Mqtt is a publish/subscribe, extremely simple and lightweight messaging protocol. If server is a publisher and client browser subscribe the topic which server publish to, then server can push message to client directly.

Mqtt是一个发布/订阅,非常简单和轻量级的消息传递协议。如果服务器是发布者并且客户端浏览器订阅服务器发布到的主题,则服务器可以直接将消息推送到客户端。

Some useful resource:

一些有用的资源:

Mosquitto is an open sourced mqtt server. Easy to install and configure.

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

mqtt-client is a proven powerful java mqtt client.

mqtt-client是经过验证的强大的java mqtt客户端。

#3


4  

Use Node JS and socket.io

使用Node JS和socket.io

This technology chooses the best transportation method based on the browser that the client is using.

该技术基于客户端使用的浏览器选择最佳的传输方法。

For latest browsers it uses Web Sockets and for others it degrades gracefully to Flash Socket or Long Pooling. See more here

对于最新的浏览器,它使用Web套接字,而对于其他浏览器,它会优雅地降级为Flash Socket或Long Pooling。在这里查看更多

What you need to do is set up a server using these technologies. The server would run at a particular port. All clients would listen to that port and server would be able to push data to the client through that port.

您需要做的是使用这些技术设置服务器。服务器将在特定端口运行。所有客户端都会监听该端口,服务器可以通过该端口将数据推送到客户端。

#4


4  

Comet also known as Reverse Ajax, is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it.

Comet也称为Reverse Ajax,是一种Web应用程序模型,其中长时间持有的HTTP请求允许Web服务器将数据推送到浏览器,而浏览器不会明确请求它。

Comet (AKA long lived http, server push) allows the server to start answering the browser's request for information very slowly, and to continue answering on a schedule dictated by the server. For more information about Comet, see the following:

Comet(AKA长期存在的http,服务器推送)允许服务器开始非常缓慢地回答浏览器的信息请求,并继续按照服务器规定的时间表回答。有关Comet的更多信息,请参阅以下内容:

DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible. With Reverse Ajax, DWR allows Java code running on a server to use client side APIs to publish updates to arbitrary groups of browsers. This allows interaction 2 ways - browser calling server and server calling browser. DWR supports Comet, Polling and Piggyback (sending data in with normal requests) as ways to publish to browsers.

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

DWR provides integration with Spring, Struts, Guice, Hibernate and others. You can read more from here.

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

Other Comet and Reverse AJAX frameworks:

其他Comet和Reverse AJAX框架:

#5


2  

but after session.save(user) the aftersave method does not get triggered.

但是在session.save(用户)之后,aftersave方法不会被触发。

  • @PostPersist is a JPA callback.
  • @PostPersist是一个JPA回调。
  • session.save() is a non-JPA, hibernate proprietary method. JPA uses entityManager.persist().
  • session.save()是一个非JPA,hibernate专有方法。 JPA使用entityManager.persist()。
  • you're using incompatible features
  • 你正在使用不兼容的功能

#6


2  

Check for update from server on every 30 Seconds or as per requirement.

每隔30秒或根据要求检查服务器的更新。

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

}, 30000);

#1


13  

Sounds like a task for WebSockets. It is part of Java EE 7 so the Glassfish should be one of the first AS that will support it.

听起来像WebSockets的任务。它是Java EE 7的一部分,因此Glassfish应该是第一个支持它的AS之一。

For intercepting the DB access you can use @PostUpdate and @PostPersist. Here is related question.

要拦截数据库访问,您可以使用@PostUpdate和@PostPersist。这是相关的问题。

There are many ways to do the so called Server Push for notifying the connected clients:

有许多方法可以执行所谓的服务器推送以通知连接的客户端:

  • polling (the link you've provided in the question ("Are we there yet? Are we there yet? ..."))
  • 民意调查(你在问题中提供的链接(“我们还有吗?我们还在吗?......”))
  • long polling (smarter way of polling - long-lived HTTP technique using keepalive messages)
  • 长轮询(更智能的轮询方式 - 使用keepalive消息的长期HTTP技术)
  • WebSockets (JSR 356)
  • WebSockets(JSR 356)
  • piggy-backing
  • 捎带
  • SPDY(wiki)
  • SPDY(维基)
  • Server-Sent Events (related answer, wiki)
  • 服务器发送的事件(相关答案,维基)

EDIT: In the Java world, there are couple of frameworks where server push (reverse ajax) is implemented out-of-the box. If you are familiar with GWT, I would suggest Errai. Other alternative is the Atmospere. The downside of the Atmospere is the fact that it requires standalone running process next to your regular application server with your web app. I was playing with it a year ago so this may have been changed since then.

编辑:在Java世界中,有几个框架,其中服务器推送(反向ajax)是开箱即用的。如果您熟悉GWT,我会建议Errai。另一种选择是Atmospere。 Atmospere的缺点是它需要使用您的Web应用程序在常规应用程序服务器旁边的独立运行过程。一年前我正在玩它,所以从那时起可能已经改变了。

In general, it is hard to provide you with a concrete piece of code, because it depends on the framework you will choose. I am familiar with Errai so here is an example in it:

通常,很难为您提供具体的代码,因为它取决于您将选择的框架。我熟悉Errai,所以这里有一个例子:

Server Side:

服务器端:

@ApplicationScoped
public class TickerService {

  @Inject
  private Event<Tick> tickEvent;

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

Client Side:

客户端:

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

    // update the UI with the new data
  }
}

Other benefits of using the Errai is having the CDI on the server and on the client out-of-the-box, another thing that is nice is using the web-sockets under the covers if it is supported and falling back to other solutions otherwise.

使用Errai的其他好处是将CDI放在服务器上和开箱即用的客户端上,另一件好事就是使用支持下的网络套接字,如果支持则退回到其他解决方案,否则。

Whatever you choose, it should fit to your existing infrastructure and to your client side UI framework.

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

#2


4  

mqtt can be used for server pushing and message broadcasting.

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

There are more detail information in http://mqtt.org/.

http://mqtt.org/中有更多详细信息。

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

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

Updated: Jul 11, 2013

更新时间:2013年7月11日

Mqtt is a publish/subscribe, extremely simple and lightweight messaging protocol. If server is a publisher and client browser subscribe the topic which server publish to, then server can push message to client directly.

Mqtt是一个发布/订阅,非常简单和轻量级的消息传递协议。如果服务器是发布者并且客户端浏览器订阅服务器发布到的主题,则服务器可以直接将消息推送到客户端。

Some useful resource:

一些有用的资源:

Mosquitto is an open sourced mqtt server. Easy to install and configure.

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

mqtt-client is a proven powerful java mqtt client.

mqtt-client是经过验证的强大的java mqtt客户端。

#3


4  

Use Node JS and socket.io

使用Node JS和socket.io

This technology chooses the best transportation method based on the browser that the client is using.

该技术基于客户端使用的浏览器选择最佳的传输方法。

For latest browsers it uses Web Sockets and for others it degrades gracefully to Flash Socket or Long Pooling. See more here

对于最新的浏览器,它使用Web套接字,而对于其他浏览器,它会优雅地降级为Flash Socket或Long Pooling。在这里查看更多

What you need to do is set up a server using these technologies. The server would run at a particular port. All clients would listen to that port and server would be able to push data to the client through that port.

您需要做的是使用这些技术设置服务器。服务器将在特定端口运行。所有客户端都会监听该端口,服务器可以通过该端口将数据推送到客户端。

#4


4  

Comet also known as Reverse Ajax, is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it.

Comet也称为Reverse Ajax,是一种Web应用程序模型,其中长时间持有的HTTP请求允许Web服务器将数据推送到浏览器,而浏览器不会明确请求它。

Comet (AKA long lived http, server push) allows the server to start answering the browser's request for information very slowly, and to continue answering on a schedule dictated by the server. For more information about Comet, see the following:

Comet(AKA长期存在的http,服务器推送)允许服务器开始非常缓慢地回答浏览器的信息请求,并继续按照服务器规定的时间表回答。有关Comet的更多信息,请参阅以下内容:

DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible. With Reverse Ajax, DWR allows Java code running on a server to use client side APIs to publish updates to arbitrary groups of browsers. This allows interaction 2 ways - browser calling server and server calling browser. DWR supports Comet, Polling and Piggyback (sending data in with normal requests) as ways to publish to browsers.

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

DWR provides integration with Spring, Struts, Guice, Hibernate and others. You can read more from here.

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

Other Comet and Reverse AJAX frameworks:

其他Comet和Reverse AJAX框架:

#5


2  

but after session.save(user) the aftersave method does not get triggered.

但是在session.save(用户)之后,aftersave方法不会被触发。

  • @PostPersist is a JPA callback.
  • @PostPersist是一个JPA回调。
  • session.save() is a non-JPA, hibernate proprietary method. JPA uses entityManager.persist().
  • session.save()是一个非JPA,hibernate专有方法。 JPA使用entityManager.persist()。
  • you're using incompatible features
  • 你正在使用不兼容的功能

#6


2  

Check for update from server on every 30 Seconds or as per requirement.

每隔30秒或根据要求检查服务器的更新。

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

}, 30000);