Merhabalar arkadaşlar malumunuz uzun süredir üzerinde çalıştığım sosyal amaçlı bir proğram yazmıştık , 112 KOBİS (Komuta Bilgi Sistemi ) , şimdilerde ikinci versiyonu yapıyorum, rest api aracılığı ile bilgiler dışarıdan geliyor, kullanıcı bilgileri doğrulandıktan sonra veritabanındaki ilgili tabloya kaydoluyor, buraya kadar sıkıntı yok, ama her yeni veri kontrolü için sayfayı yenilememiz gerekiyor aksi takdirde bu yeni bilgiden haberimiz olmuyor, ilgili taploya yeni bir veri eklendiğinde ekrana anlık uyarı verdirmek istiyorum, bunu her dakika git tabloyu kontrol et eğer sayıda artış varsa refresh yap ve ekrana bas mantığının dışında, daha pratik bir yol var ise öneride bulunursanız sevinirim selamlar.
Api Aracılığı İle Gelen Yeni Veri Olursa Ekrana Bildirim Çıkartmak
- Düzenlendi
Pratik olan ajax ile periyodik kontrol; zahmetli ama real-time diyebileceğimiz yol ise broadcasting. Sizin işte ajax sunucuyu pek yoracak gibi durmuyor o yüzden ajax ile yapın gitsin.
setInterval(function() {
$.post( "/api/kontrol", function(response) {
if(response.updated) {
// yeni kayıt var, uyarı verelim
}
});
}, 2000);
Route::post('api/kontrol')->uses('ApiController@kontrol')->name('api.kontrol');
// ApiController::kontrol()
public function kontrol()
{
$yeniKayitSayisi = User::yeniKayit()->count();
return response()->json([
'updated' => (bool) $yeniKayitSayisi,
'count' => yeniKayitSayisi,
'checked_at' => Carbon::now()
]);
}
en iyi yontem socket bağlantı; mgsmusun dediğini kolay yaparsın ama klasik javascript kodu o...browser durursa o da durur
browseri kapatırsan oda kapanır..geçici çözüm istiyorsan kullan ama doğrusu socket bağlantıdır real-time işler için.

Aslında OneSignal'in rest apisi ile php kullanarak web push bildirimleri ile tarayıcı bildirimleri de kullanılabilir.
Bu konuda tek önerebileceğim Socket.IO dur.
Web Yazılımının en büyük eksiği tetikleme sorunudur. Dışarıda tetiklenemez ve bunu yapabilmek için çeşitli yöntemler mevcut. Birisi mgsmus arkadaşımızın verdiği Javascript timer özelliğidir. Fakat bu işlem uzun vadede sıkıntı yaratır, sürekli işlem tarayıcınızın cache'ini şişirecek bu da kullanıcıya yansıyacaktır.
NodeJS + Socket.IO en pratik ve en profesyönel çözümlerden biridir.
https://github.com/socketio/socket.io
https://github.com/mysqljs/mysql
NodeJS ile mysql işlemleri de yapmak isterseniz diğer link'i de kontrol etmenizi öneririm.
Web Yazılımının en büyük eksiği tetikleme sorunudur. Dışarıda tetiklenemez ve bunu yapabilmek için çeşitli yöntemler mevcut. Birisi mgsmus arkadaşımızın verdiği Javascript timer özelliğidir. Fakat bu işlem uzun vadede sıkıntı yaratır, sürekli işlem tarayıcınızın cache'ini şişirecek bu da kullanıcıya yansıyacaktır.
NodeJS + Socket.IO en pratik ve en profesyönel çözümlerden biridir.
https://github.com/socketio/socket.io
https://github.com/mysqljs/mysql
NodeJS ile mysql işlemleri de yapmak isterseniz diğer link'i de kontrol etmenizi öneririm.
SetInterval zamanlayıcı işlevi aslında javascriptin specifikasyonunda bulunmayan bir yontem; javascript bunu browserin zamanlayıcısına güvenerek yaptırıyor.Bu da aslında büyük sorunlara gebe; zira bu yontemin en buyuk eksiği; geri bildirim işlevinin çalışıp çalışmadığı umrunda değil. . zamanlayıcı aşımı geldiğinde bunu browserin yığınına atar ve geri bildirim ilk sıradaysa ne ala; çalışır.yığında bir sürü iş varsa sırası gelmeden çalışmaz.
Artı olarak; uzak sunucuya baglandığınızı deneyin; yapmadığımız şeyler değil yaptık hepimiz
socket mi vardı zamanında..ağ gecikimi,sistem hatası; karsı sunucu faili..umrunda olmaz ki setIntervalin..zamanlayıcıyı surekli devam ettirir; bir sürü demet yığını..
Artı olarak; uzak sunucuya baglandığınızı deneyin; yapmadığımız şeyler değil yaptık hepimiz

Pratik arkadaşlar, pratik
O yüzden elimden geldiğince node.js + socket.io seçeneğini en sona bırakıyorum. GkyKrkc bir proje ile ilgileniyor, ben de ona göre konuşuyorum, genel konuşmuyorum. Önce bir projesini ayağa kaldırsın, ondan sonra arkada geliştirmeye devam eder. Aşırı yükleme yapıp yakmayalım arkadaşı 


sana laf söyleyenin gözü çıksınmgsmus yazdıPratik arkadaşlar, pratikO yüzden elimden geldiğince node.js + socket.io seçeneğini en sona bırakıyorum. GkyKrkc bir proje ile ilgileniyor, ben de ona göre konuşuyorum, genel konuşmuyorum. Önce bir projesini ayağa kaldırsın, ondan sonra arkada geliştirmeye devam eder. Aşırı yükleme yapıp yakmayalım arkadaşı :)


Yok ya zaten laf olarak algılamadım, canınız sağolsun, sadece GkyKrkc'ın az çok ne bildiğini ne yaptığını forumdan takip ede ede biliyorum, O yüzden ortaya çaaat diye node ile dalmak istemedim.
7 gün sonra
Değerli arkadaşlar kusura bakmayın küçük bir ameliyat geçirdim bir süre yoktum, öncelikle vermiş olduğunuz cevaplardan dolayı çok teşekkür ederim, Ekrem hocamın da söylediği gibi sanırım bu konuda en hızlısı ve en iyisi node js socket.io diye düşünüyorum , projemde zaten form bildirimlerinde socket.io kullanıyorum, anlık bildirimleri bu sayede yakalayabiliyorum yani, ama bunu api roote üzerinde nasıl yaparım oraya takılmış durumdayım örneğin aşağıdaki kodda id si alici olan bir formdan veri gönderildiği zaman socket.io bunu yakalıyor ve id si bildirim olan div içerisinde "Yeni Kayit Bildirimi" şeklinde uyarı basıyor, aynısını
Route::post('post','PostController@add')->middleware('auth:api'); aynısını bunu api.php içindeki Route yolu üzerinden geçerken yakalamasını ve uyarı vermesini istiyorum bunu nasıl yapabilirim , bir fikri olan var mı ?
Route::post('post','PostController@add')->middleware('auth:api'); aynısını bunu api.php içindeki Route yolu üzerinden geçerken yakalamasını ve uyarı vermesini istiyorum bunu nasıl yapabilirim , bir fikri olan var mı ?
<script src="{{ asset('js/socket.io.js')}}"></script>
<script>
var socket = io.connect('http://207.154.247.100:3000');
socket.on('alici', function (data) {
var ses=new Audio('ses.mp3');
ses.play();
console.log(data.user);
$( "#bildirim" ).append( "<strong>Yeni Kayıt Bildirimi</strong>" );
});
</script>
Route::post('post','PostController@add')->middleware('auth:api');
- Düzenlendi
Geçmiş olsun.
Keşke node ve socket kullandığınızı önce söyleseydiniz, konuyla direkt alakalı çünkü.
Bu aşamaya geldiğinize göre artık broadcasting kullanacaksınız demektir.
https://laravel.com/docs/5.5/broadcasting
Yani yeni kayıt bildirimi için önce bir tane broadcast eventı oluşturacaksınız. PostController@add yöntemi içerisinde bu event ateşlenecek (kuyruğa alınacak). Daha sonra socket ile o eventı dinleyeceksiniz (alici dinlediğiniz gibi).
Buradan yola çıkabilirsiniz.
Keşke node ve socket kullandığınızı önce söyleseydiniz, konuyla direkt alakalı çünkü.
Bu aşamaya geldiğinize göre artık broadcasting kullanacaksınız demektir.
https://laravel.com/docs/5.5/broadcasting
Yani yeni kayıt bildirimi için önce bir tane broadcast eventı oluşturacaksınız. PostController@add yöntemi içerisinde bu event ateşlenecek (kuyruğa alınacak). Daha sonra socket ile o eventı dinleyeceksiniz (alici dinlediğiniz gibi).
Buradan yola çıkabilirsiniz.
geçmiş olsun gkyKrkc
Öncelikle geçmiş olsun.
mgsmus'un dediği gibi söylemen gereken en önemli şeyi "projemde zaten form bildirimlerinde socket.io kullanıyorum" en sona saklamışsın
ve yine mgsmus'un verdiği linkle halledersin problemini.
mgsmus'un dediği gibi söylemen gereken en önemli şeyi "projemde zaten form bildirimlerinde socket.io kullanıyorum" en sona saklamışsın

ve yine mgsmus'un verdiği linkle halledersin problemini.
çok teşekkür ederim üstadım, Allah razı olsun selamlarEkrem yazdıÖncelikle geçmiş olsun.
mgsmus'un dediği gibi söylemen gereken en önemli şeyi "projemde zaten form bildirimlerinde socket.io kullanıyorum" en sona saklamışsın
ve yine mgsmus'un verdiği linkle halledersin problemini.
Arkadaşlar kodlarım aşağıdaki gibi eventi ateşlemek için PostController@add fonksiyonunun içine event(new App\Events\EventYeniHasta()); yazdım daha sonra terminal üzerinden ana dizinde node socket.js yazarak socketi çalıştırdım bana 3000 portunun dinlendiği cevabını verdi, ama PostController@add fonksiyonunu çalıştırdığım zaman ana sayfadaki id si bildirim olan div içerisine datayı yazdıramıyorum acaba nerede yanlış yapıyorum.
YeniHasta Event
YeniHasta Event
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EventYeniHasta extends Event implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
use SerializesModels;
public $data;
public function __construct()
{
$this->data = array(
'power'=> '10'
);
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('YeniHasta');
}
}
master.blade.php
<div id="bildirim"></div>
<script src="{{ asset('js/jquery-3.2.1.min.js')}}"></script>
<script src="{{ asset('js/socket.io.js')}}"></script>
<script>
var socket = io.connect('http://207.154.247.100:3000');
socket.on("YeniHasta:App\\Events\\EventYeniHasta", function(message){
// increase the power everytime we load test route
$('#bildirim').text(parseInt($('#bildirim').text()) + parseInt(message.data.power));
});
</script>
socket.jsvar app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('YeniHasta', function(err, count) {
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
socket.on("YeniHasta:App\\Events\\EventYeniHasta", function(message){
console.log(message);
});
Bu şekilde konsolda çıktıyı görebiliyor musunuz?Bir de broadcastOn kısmında PrivateChannel kullanmışsınız yani sayfaya üye girişi yapılması lazım değil mi?
Bir de arka planda kuyruk işlemcisi çalışıyor değil mi?
mgsmus Üstadım kuyruk işlemciden kastımız, terminale yazdığımız node socket.js nin aktif edilip edilmediği mi ? yoksa başka bişey mi
karıştırdım bir an, socket 3000 portunu dinliyor şuan aktif

Sizin EventYeniHasta ShouldBroadcast arayüzünü gerçeklediği için ateşlenmek üzere kuyruğa alınacak demektir.
Kuyruğa alınan olayın çalıştırılabilmesi için de php artisan queue:work şeklinde arka planda ayrıca kuyruk işleyicisinin çalışması lazım.
Kuyruğa alınan olayın çalıştırılabilmesi için de php artisan queue:work şeklinde arka planda ayrıca kuyruk işleyicisinin çalışması lazım.
- Düzenlendi
Bunların hepsini yaptım, Node Js ve socket io çalışıyor, Redis çalışıyor, AppServiceProvider içindeki Broadcast claslarını aktifleştirdim buralarda sorun yok , kodlarımı tekrar paylaşıyorum bir yerde atladığım bir olay var ama bulamıyorum, terminalde php artisan queue:work yazdım herhangi bir cevap alamadım ekran bekledi durdu. sanırım bırakacam vazgeçecem bu işten :)) sonuna kadar gelip küçük bir hata yüzünden vazgeçmeyeyeyim dedim son olarak sizlerin onayına sunuyorum. hepinize saygılar.
EventYeniHasta.php
EventYeniHasta.php
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EventYeniHasta implements ShouldBroadcast
{
use SerializesModels;
public $message;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
// return new PrivateChannel('statusChanged');
return ['test-channel'];
}
}
PostController@add methodu
namespace App\Http\Controllers;
use App\Events;
use App\Transformers\PostTransformer;
use App\Events\EventYeniHasta;
use Illuminate\Http\Request;
use App\Post;
use Illuminate\Support\Facades\Auth;
class PostController extends Controller
{
public function add(Request $request, Post $post)
{
event(new EventYeniHasta('Yeni Hasta Eklendi'));
$this->validate($request,[
'tc' => 'required|min:10',
'adi' => 'required',
'soyadi' => 'required'
]);
$post=$post->create([
'user_id' => Auth::user()->id,
'tc' => $request->tc,
'adi' => $request->adi,
'soyadi' => $request->soyadi,
]);
$response =fractal()
->item($post)
->transformWith(new PostTransformer)
->toArray();
return response()->json($response,201);
}
socket.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('test-channel', function(err, count) {
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
master.blade.php
<div id="bildirim">Uyarı Burada Çıkacak</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script type="text/javascript">
var socket = io('http://207.154.247.100:3000');
socket.on("test-channel:App\\Events\\EventYeniHasta", function(message){
console.log("Merhaba");
alert("deneme");
//$('#bildirim').text(parseInt($('#bildirim').text()) + parseInt(message.data));
});
</script>
.env
BROADCAST_DRIVER=redis
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=redis
- Düzenlendi
Yeni hasta eklendiğinde bildirim göndermeyi hemen yapacaksanız kuyruğa almanıza gerek yok. Doğrudan controller içinde redis ten paylaşıp Nodejs tarafında dinleyip yayınlayabilirsiniz neden iki iş yapıyorsunuz?
Controller içerisinde redis e göndermek istediğimiz veri $data değişkeninde olsun.
Redis'te dinlemek istediğimiz kanal dinlenecekKanal olsun. Aşağıdaki şekilde redis'te publish edebiliriz.
Controller içerisinde redis e göndermek istediğimiz veri $data değişkeninde olsun.
Redis'te dinlemek istediğimiz kanal dinlenecekKanal olsun. Aşağıdaki şekilde redis'te publish edebiliriz.
$data =[
'message'=>'Yeni Hasta Eklendi',
'baskabirsey'=>'Başka bir data'
];
Redis::publish('dinlenecekKanal', json_encode($data));
Daha sonra Nodejs tarafında bu kanalı subscribe edip gelen datayı alabiliriz.
var redis = require("redis")
, subscriber = redis.createClient()
, publisher = redis.createClient();
subscriber.auth('egerVarsaRedisSifreniz');
publisher.auth('egerVarsaRedisSifreniz.');
subscriber.on("message", function(kanal, mesaj) {
//burada channel ile kanal ismini, message ile de Laravel'de gönderdiğimiz $data değişkenindeki array'i alabiliriz.
// artık bu mesaj ile neler yapabiliriz senin ihtiyacına kalmış.
// Socket'e gönderebilirsin, Mongodb ye yazabilirsin, slack'e bildirim atabilirsin falan feşmekan..
console.log(kanal);
console.log(" kanalından");
console.log(mesaj);
console.log("mesajı yayınlandı");
// diyelim veriyi işledin birşeyler yaptın yeniden laravel e göndereceksin,
// publisher ile de yeniden redis te paylaşabilirsin.
publisher.publish('yeniKanal', 'Yeni mesaj');
});
// burada dinlenecek kanalları yazmamız lazım. .
subscriber.subscribe("dinlenecekKanal");
//Laravel'de dinlemek için
Redis::subscribe(['yeniKanal'], function ($mesaj) {
print_r($mesaj);
});