• 13-03-2014, 11:31:16
    #19
    fatihsarac adlı üyeden alıntı: mesajı görüntüle
    tamam işte ondan bahsediyorum ben de. php ile 2. bir işlemi yapabilmek için node'dan nasıl disconnet olmayacağız? bildiğiniz bir yöntem varsa paylaşırsanız sevinirim, benim de en çok takıldığım mevzu bu.

    NodeJS serverinizi biraz optimize etmeniz gerekiyor. Timeout durumu var çünkü standartı 10 saniye. Eğer 10 saniye boyunca işlem yapmazsanız sunucudan düşüyorsunuz. Bunun için clientları serverları datasız konuşturacak ufak bir ping fonksiyonu yapabilirsiniz.

    https://github.com/LearnBoost/Socket...ring-Socket.IO

    Yukarıdaki linkte bazı optimizasyon ayarları mevcut inceleyebilirsiniz.

    Şimdi 2. işlemi yapabilmek kısmına geleyim hemen.

    io.sockets.on('connection', function(socket) 
    {
    	
    	//Kullanıcı bağımsız idsi
    	var userID = socket.handshake.query.userID;
    	//Kullanıcı bilgilerini alalım.
    	clients[userID] = { socket: socket };
    	           	
    	socket.on('Function1', function() {
    	});
    	socket.on('Function2', function() {
    	});
    	socket.on('Function3', function() {
    	});
    	
    });
    Şimdi aşağıda gördüğünüz gibi connection fonksiyonu içerisinde yazdığınız tüm fonksiyon connect olmuş kişi için geçerlidir. userID değişkeni kişi disconnect olana kadar onun olmuş oluyor. İçerideki tüm işlemlerde kullanılabilir. Burada querystring ile yaptım ben header ilede yapılabilir. Yani kullanıcı sockete bağlı sürece tekrar socket.connect(); göndermeye gerek yok.

    Disconnect durumunuda aşağıdaki gibi kullanırsanız.

      socket.on('disconnect', function(socket) {	
    delete clients[userID];
    });
    Kullanıcı gittiğinde onunla etkileşimimizi kesmiş oluruz.

    Her bir connection bir kişi olmuş oluyor böylece. Her bir istek bir kullanıcı değil.
  • 13-03-2014, 11:41:25
    #20
    bluemansiiz adlı üyeden alıntı: mesajı görüntüle
    NodeJS serverinizi biraz optimize etmeniz gerekiyor. Timeout durumu var çünkü standartı 10 saniye. Eğer 10 saniye boyunca işlem yapmazsanız sunucudan düşüyorsunuz. Bunun için clientları serverları datasız konuşturacak ufak bir ping fonksiyonu yapabilirsiniz.

    https://github.com/LearnBoost/Socket...ring-Socket.IO

    Yukarıdaki linkte bazı optimizasyon ayarları mevcut inceleyebilirsiniz.

    Şimdi 2. işlemi yapabilmek kısmına geleyim hemen.

    io.sockets.on('connection', function(socket) 
    {
    	
    	//Kullanıcı bağımsız idsi
    	var userID = socket.handshake.query.userID;
    	//Kullanıcı bilgilerini alalım.
    	clients[userID] = { socket: socket };
    	           	
    	socket.on('Function1', function() {
    	});
    	socket.on('Function2', function() {
    	});
    	socket.on('Function3', function() {
    	});
    	
    });
    Şimdi aşağıda gördüğünüz gibi connection fonksiyonu içerisinde yazdığınız tüm fonksiyon connect olmuş kişi için geçerlidir. userID değişkeni kişi disconnect olana kadar onun olmuş oluyor. İçerideki tüm işlemlerde kullanılabilir. Burada querystring ile yaptım ben header ilede yapılabilir. Yani kullanıcı sockete bağlı sürece tekrar socket.connect(); göndermeye gerek yok.

    Disconnect durumunuda aşağıdaki gibi kullanırsanız.

      socket.on('disconnect', function(socket) {	
    delete clients[userID];
    });
    Kullanıcı gittiğinde onunla etkileşimimizi kesmiş oluruz.

    Her bir connection bir kişi olmuş oluyor böylece. Her bir istek bir kullanıcı değil.
    mevzu node tarafıyla alakalı değil ama mevzu php tarafıyla alakalı.

    şöyle açıklıyayım;

    1. kullanıcımız php sayfamıza girdi, aynı anda kullanıcı adını kullanarak node / socket.io üzerinde bağlantı oluşturdum. node bu kullanıcı için kendi ID değerini oluşturdu (bağlantı bilgilerini).

    2. kullanıcımız sayfa değiştirdi. otomatik olarak ne oldu? socket bağlantısı koptu. girdiği sayfada ne yaptık? tekrar node/socket.io bağlantısı oluşturduk. bu sefer ilk oluşan değerlerin tamamı değişti.

    burada şöyle bir ihtiyaç doğuyor; php ile bağlantı sağladığımız kullanıcı bilgilerini sabitlemek. ne kadar sayfa değiştirirse değiştirsin, ne işlem yaparsa yapsın, php tarafında session da kaldığı süre boyunca node/socket.io tarafındaki bilgisi sabit kalsın.

    malesef bu mümkün değil (en azından benim araştırmalarım ve denemelerim sonucunda).

    çözüm var mı? var ama hamallık;

    veritananında bir tablo oluştururuz. bu tabloda kullanıcı adını ve socket id'sini yazdıracağımız alanlar olur. kullanıcı her bağlandığında bu alanı güncelleriz ki diğer kullanıcılar ile kullanıcımız node üzerinden iletişime geçerse sorun olmasın.
  • 13-03-2014, 11:54:41
    #21
    fatihsarac adlı üyeden alıntı: mesajı görüntüle
    mevzu node tarafıyla alakalı değil ama mevzu php tarafıyla alakalı.

    şöyle açıklıyayım;

    1. kullanıcımız php sayfamıza girdi, aynı anda kullanıcı adını kullanarak node / socket.io üzerinde bağlantı oluşturdum. node bu kullanıcı için kendi ID değerini oluşturdu (bağlantı bilgilerini).

    2. kullanıcımız sayfa değiştirdi. otomatik olarak ne oldu? socket bağlantısı koptu. girdiği sayfada ne yaptık? tekrar node/socket.io bağlantısı oluşturduk. bu sefer ilk oluşan değerlerin tamamı değişti.

    burada şöyle bir ihtiyaç doğuyor; php ile bağlantı sağladığımız kullanıcı bilgilerini sabitlemek. ne kadar sayfa değiştirirse değiştirsin, ne işlem yaparsa yapsın, php tarafında session da kaldığı süre boyunca node/socket.io tarafındaki bilgisi sabit kalsın.

    malesef bu mümkün değil (en azından benim araştırmalarım ve denemelerim sonucunda).

    çözüm var mı? var ama hamallık;

    veritananında bir tablo oluştururuz. bu tabloda kullanıcı adını ve socket id'sini yazdıracağımız alanlar olur. kullanıcı her bağlandığında bu alanı güncelleriz ki diğer kullanıcılar ile kullanıcımız node üzerinden iletişime geçerse sorun olmasın.
    Sayfa değiştirme işlemi yapmak nodejs kullandığın yerlerde ihtiyacın olmaması gereken bir durum değil mi ? Ayrıca session üzerinde tutabilirsin socket bilgisini ? Nasıl kendi login işlemi tutabiliyorsun onuda tutabilirsin. Bu arada tekrar connect olmak demek kullanıcı değiştiği anlamına gelmez. Söylediğim gibi socketi client'ta tutabildiğin gibi kullanıcıyı sockette yakalayabilirsin. Disconnect olması tekrar connect olması sorun değil. Sonuç itibariyle nodejs tarafı çökebilirde ? Yani tekrar connect gerektirebilecek durumlar elbet var. Bu bir sorun değil aslına bakarsan.

    Gelelim senin sorunun asıl cevabına;

    şimdi clients bir dizimiz olsun. Bu diziye kullanıcıları tanımlayalım. Örneğin clients["samet"] bu benim bağlantı bilgim olsun. Her connect oluşumda bu dizi elemanı benim olacaktır. Yani ahmet mehmet farketmez clients["samet"].socket dediği anda o bilgi bana gelir. Client'ın tekrar connect olması bu durumu etkilemez veya değişen bir durum olmaz. Socket sana yeni tanımlamalar yapsada sen tek yeri sorgular ve bakarsın.
  • 13-03-2014, 12:05:50
    #22
    dark_way adlı üyeden alıntı: mesajı görüntüle
    @PsiCat; paylaşım için teşekkürler. Böyle bi anda yığınla kod epey karışık geldi ama incelicem.
    Kusura bakmayın. Sanırım bazı açıklamalar yapmadan, paylaştığım kodların da aslında bir yararı olmayacak.

    Öncelikle Node.js ile programlamaya başlamadan önce Coffeescript dilini incelemenizi öneririm. Coffeescript, özellikle, herhangi bir ek Javascript kütüphanesine gerek kalmadan, saf Javascript kodları ile kolayca nesne yönelimli programlar yazmanız konusunda yardımcı olabilir. Coffeescript ile kodlarınızı yazıp çalıştırmak için basitçe NPM ile Coffeescript kütüphanesini indirin ve kodlarınızı aşağıdaki şekilde çalıştırın;
    $ coffee server.coffee
    "Derlenmiş Javascript kodları" başlığındaki kodları incelemenize gerek yok. O kodlar Coffee script ile yazdığım kodların Javascript'e çevrilmiş halleri. Yani asıl incelemeniz gereken kodlar "Coffeescript kodları." başlığındaki kodlar. Sanırım bu kodları da anlaşılır şekilde, PHP karşılıkları ile birlikte biraz açıklamam yerinde olur.





    Not: Sadece Sunucu sınıfını açıkladım. Sunucu sınıfını anlarsanız Client sınıfını da anlayabilirsiniz.

    1. Burada bir "Server" sınıfı oluşturuyorum ve "Singleton" tasarım kalıbını uyguluyorum. Zira program akışı sırasında ikinci sunucuya ihtiyaç yok. Dahası ikinci bir sunucunun oluşturulmaması şart. Ayrıca programın her yerinde sunucuya Server.get() methodu ile ulaşabilirim.

    class Server
      instance = null
    
      @get: ->
        unless instance?
          instance = new @
          instance._init()
    
        instance
    class Server
    {
      private static $instance = null;
    
      public static function get()
      {
        if(!isset(static::$instance))
        {
          static::$instance = new Server();
          static::$instance->_init();
        }
    
        return static::$instance;
      }
    }
    2. _init; sunucu çalıştırıldığında çağırılan ilk metod. clients bağlanacak kullanıcıları muhafaza edecek olan dinamik, boş bir nesne. io ise socket.io nesnesi.

      _init: ->
        @clients = { }
        @io = require("socket.io")
    public $clients;
    public $io;
    
    private function _init()
    {
      $this->clients = new stdClass();
      $this->io = require("socket.io");
    }
    3. _initCallbacks sunucunun başlatılması ile, start metodu tarafından çağrılan ve sunucunun yerleşik socket.io işelmlerini, sınıf metodlarına yönlendirecek olan metoddur. authorization ile gelen her bağlantıyı, bağlanma aşamasında kontrol edebiliriz. Böylece geçersiz kullanıcı bilgileri ile giriş yapmaya çalışan kişilerin istekleri ile sunucu arasında bir kontrol katmanı eklemiş oluruz. Normal şartlarda authorization her kullanıcıyı kabul eder.

    _initCallbacks: =>
      @io.set 'authorization', @_authorization
      @io.sockets.on "connection", @_onConnect
    private function _initCallbacks()
    {
      $this->io->set('authorization', $this->_authorization);
      $this->io->on('connection', $this->_onConnect);
    }
    4. Burada çok basit bir kontrol söz konusu. Bağlanan kullanıcının kullanıcı adının şu an sunucuya başlı olup olmadığı kontrol ediliyor. Eğer bu kullanıcı adı alınmış ise 'Bu kullanıcı su an bagli.' şeklinde bir hata ile kullanıcıyı geri çeviriyor. Mantıken burası kullanıcı adı ve şifresini veritabanından karşılaştıracağınız en iyi nokta. Bazı kişiler soket bağlantısını kabul ettikten sonra bu kontrolü 'onLogin' gibi ikinci bir istekte yapıyorlar ancak ben bunun tasvip etmiyorum.

    _authorization: (handshake, callback) =>
      username = handshake.query.username
      handshake.username = username
      for id, client of @clients
        return callback('Bu kullanıcı su an bagli.', false) if client.username == username
        callback(null, true)
    private function _authorization($handshake, $callback)
    {
      $username = $handshake->query->username;
      $handshake->username = username;
      foreach($clients as $client)
        if($client->username == $username)
          return $callback('Bu kullanıcı su an bagli.', false);
    
      return $callback(null, true);
    }

    5. _authorization kontrolleri akabinde eğer kullanıcının soket bağlantısı kabul edilirse _onConnect metodu çağrılır. Kabul edilmeyen bağlantılar sunucu katmanına ulaşamadan geri çevrilir. Burada kullanıcının soketi ile yeni bir Client nesnesine oluşturulur ve clients değişkenine kaydedilir. Böylece sunucuya bağlanan bütün kullanıcılar üzerinde istediğiniz her türlü işlemi ve takibi kendi kurallarınız ile gerçekleştirebilirsiniz. socket.io aslında bu tür işlemler için bazı yerleşik imkanlar sunuyor ancak bunlar sadece çok basit işlemler için kullanılmaya müsait. Daha güçlü ve esnek bir kontrol için bu tür bir nesne yönelimli yapı kullanmanız daha faydalı.


    _onConnect: (socket) =>
      @clients[socket.id] = new Client(@, socket, socket.handshake.username)
    private function _onConnect($socket)
    {
      $this->clients->{$socketId = $socket->id} = new Client($this, $socket, $socket->handshake->username);
    }
    6. start açıkça belli olduğu üzere sunucuyu başlatan metoddur. Buradaki önemli nokta io örnek değişkeninin listen metodu üzerinden dönen socket.io manager nesnesine atanması. Sınıfta kullandığımız pek çok metod aslında bu nesneye aittir. İkinci olarak io üzerinde gerekli olan callback metodlarını tanımlamak için _initCallbacks metodu çağrılıyor.

    start: =>
      @io = @io.listen(3000)
      @_initCallbacks()
      console.log("Sunucu dinliyor.")
    public function start()
    {
      $this->io = $this->io->listen(3000);
      $this->_initCallbacks();
      echo "Sunucu dinliyor.";
    }
    7. sendAll ile sunucuya bağlı olan bütün kullanıcılara mesaj gönderebilirsiniz.

    sendAll: (args...) =>
      @io.sockets.emit.apply(@io.sockets, args)
    public function sendAll()
    {
      call_user_func(array($this->io->sockets, 'emit'), func_get_args());
    }
    8. Gerekli noktalarda herhangi bir Client nesnesine ulaşmak istediğinizde socket ID değeri ile bu kullanıcıya ulaşabilirsiz.

    getClient: (id) =>
      @clients[id]
    public function getClient($id)
    {
      return $this->clients->{$id};
    }
  • 24-07-2014, 21:01:32
    #23
    Kimlik doğrulama veya yönetimden onay bekliyor.
    Node.js baştan sonra öğrenmek isteyenler bu eğitim setine göz atabilirler (5 DOLARLIK İNDİRİM KODU )https://www.udemy.com/nodejs-socketi...de=FJKTHEGOD10