2017-11-06 93 views

cevap

5

ancak postgresql-async kütüphane yapar:

Ben buna benzer bir şey yapmak istiyorum. Bir bir Akka Streams Source oluşturmak ve bir müşteriye veritabanı bildirimleri akışları Play son nokta bunu dahil etmek ikincisi kullanabilirsiniz: Yukarıdaki denetleyici olarak

package controllers 

import javax.inject.{Inject, Singleton} 

import akka.actor._ 
import akka.stream._ 
import akka.stream.scaladsl._ 

import com.github.mauricio.async.db.postgresql.PostgreSQLConnection 
import com.github.mauricio.async.db.postgresql.util.URLParser 
import com.github.mauricio.async.db.util.ExecutorServiceUtils.CachedExecutionContext 

import play.api.Logger 
import play.api.http.ContentTypes 
import play.api.libs.EventSource 
import play.api.mvc._ 

import scala.concurrent.duration._ 
import scala.concurrent.Await 

@Singleton 
class DbNotificationController @Inject()(cc: ControllerComponents, 
             materializer: Materializer) 
    extends AbstractController(cc) { 

    implicit val mat = materializer 

    val configuration = URLParser.parse("jdbc:postgresql://localhost:5233/my_db?user=dbuser&password=pwd") 
    val connection = new PostgreSQLConnection(configuration) 
    Await.result(connection.connect, 5 seconds) 

    val (actor, dbSource) = 
    Source.actorRef[String](Int.MaxValue, OverflowStrategy.dropNew) 
      .toMat(BroadcastHub.sink[String])(Keep.both) 
      .run() 

    connection.sendQuery("LISTEN my_channel") 
    connection.registerNotifyListener { message => 
    val msg = message.payload 
    Logger.debug(s"Sending the payload: $msg") 
    actor ! msg 
    } 

    def index() = Action { 
    Ok(views.html.scaladbnotification()) 
    } 

    def streamDb() = Action { 
    Ok.chunked(dbSource via EventSource.flow).as(ContentTypes.EVENT_STREAM) 
    } 
} 

, dinleyici veritabanından bir bildirim alır, bildirimdeki yük (bir String) günlüğe kaydedilir ve bir aktöre gönderilir. Bu aktöre gönderilen mesajlar, streamDb uç noktasında kullanılan Source beslenir. Yüklü mesajlar müşteriye gönderilmeden önce, Play'in EventSource sınıfına dönüştürülür.


Ben denemeler için kullanabileceğiniz Play streaming example application gelen DbNotificationController uyarlanmış. Bunu yapmak isterseniz, belli ki o projeye DbNotificationController entegre etmek gerekir:

  1. build.sbt için "com.github.mauricio" %% "postgresql-async" % "0.2.21" ekleyin.
  2. PostgreSQL'i gereken şekilde ayarlayın, NOTIFY da dahil olmak üzere ve denetleyicideki veritabanı URL'sini yapılandırmanıza göre ayarlayın.
  3. Kopyalayıp /app/controllers/'a yapıştırın.
  4. Kopya app/views/ içine aşağıdaki dosyası (scaladbnotification.scala.html diyoruz):
@main { 

    <h1>Server Sent Event from DB</h1> 

    <h1 id="db"></h1> 

    <p> 
     DB events are pushed from the Server using a Server Sent Event connection. 
    </p> 

    <script type="text/javascript" charset="utf-8"> 
     if (!!window.EventSource) { 
      var stringSource = new EventSource("@routes.DbNotificationController.streamDb()"); 
      stringSource.addEventListener('message', function(e) { 
       $('#db').html(e.data.replace(/(\d)/g, '<span>$1</span>')) 
      }); 
     } else { 
      $("#db").html("Sorry. This browser doesn't seem to support Server sent event. Check <a href='http://html5test.com/compare/feature/communication-eventSource.html'>html5test</a> for browser compatibility."); 
     } 
    </script>  
} 

    /conf/routes dosyasında
  1. ekleyin aşağıdaki satırları:
  1. sbt run ile uygulamasını başlatın ve tarayıcınızda aşağıdaki URL'ye

    :

    http://localhost:9000/scala/dbNotification