Arkadaşlar yeni bir uygulama geliştiriyorum, uygulamanın kalan kısımları tamamen bitti, çalışır vaziyette sadece chat sistemini yapmam lazım ama o konuda bir tecrübeye sabit değilim. Github ve diğer kaynaklardan bulduğum chat paketleri de açıkcası biraz komplike geldi ve sisteme entegre etmem zor gibi görünüyor sizin bildiğiniz bir paket veya önerebileceğiniz bir yol var mı bunun için? Uygulamada arkadaş ekleme vs özellikleri çalışıyor sadece konuşa bastığımda o kişi ile olan chat ekranının açılıp Node JS ile konuşmaları gerçekleştirmem gerekecek. Diğer paketlere baktığımda kendi üyelik sistemleri benim işime yaramayacak onlarca özellik vs var ve kurcalamaya çalıştığım zaman işin içinden çıkamıyorum.

  • HseyinAkkaya replied to this.
    • muratapps _socket oluşturulurken forceNew parametresini true set edip nodejs tarafında

      socket.on('disconnect', function() {
      // handle disconnect
      socket.disconnect();
      socket.close();
      });

      yapmayı deneyin bir de

    muratapps
    https://fluttergems.dev/chat/
    bu sayfadan bakabilirsin hatta
    https://pub.dev/packages/flutter_firebase_chat_core
    bu sanki işe yarar gibi göründü.
    Açıkcası ben olsam kullanmazdım. Çünkü chat sistemi adı üstünde bir sistem ve kendine göre uyarlayarak, kendin sistemi kurman daha mantıklı, kolay ve güvenli olur diye düşünüyorum. Yarın bir yerde hata aldığında bulman, düzenlemen ve hatta geliştirmen çok daha kolay olur. UI tarafında paket kullanabilirsin.
    Örneğin https://pub.dev/packages/flutter_chat_ui
    burada hazır ui tasarımı var.
    Service tarafını da hazırladığın apiler ile iletişime geçecek, kendi auth sisteminle entegre çalışacak şekilde hazırlamalısın.

    HseyinAkkaya Yanıtın için teşekkürler bu süreç içerisinde aslında basit bir mantıkta çalışan bir sistem yaptım ancak bazı yerlerde hata alıyorum onları çözebilirsem ilerleyebilirim gibi.

    Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
    E/flutter ( 4767): Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.
    şu an böyle bir hata alıyorum. Chat Paketi bu kişinin yapmış olduğu paket üzerinden geliştirme yaparak gönderilen mesajları veritabanına vs kaydettirdim. Sistem basit ama çalışıyor ufak tefek sıkıntılar haricinde 🙂

    İki adet başlıca sorunum var. Bunlardan birisi mesajları kime gönderirsem göndereyim her kullanıcının ekranına düşüyor filtrelemeyi bir türlü yapamadım sender ve receiver ID’lerini alıyorum ona göre if blokları ekledim node js üzerinde ama yinede bir yerde hata yapıyorum sanırım.

    İkinci hata ise, uygulamayı ilk kez açıp bir kullanıcıyla mesajlaşmaya girip bir şeyler gönderince sorun yok mesajlar gidiyor ancak bir sayfa geri gelip başka kullanıcıya tıklayıp yeni mesaj göndermeye başlayınca en üstte ki hatayı alıyorum hatanın olduğu satırda şu kod var:

    _connectSocket() {
    _socket.onConnect((data) => print('Connection established'));
    _socket.onConnectError((data) => print('Connect Error: $data'));
    _socket.onDisconnect((data) => print('Socket.IO server disconnected'));
    _socket.on(
    'message',
    (data) => Provider.of<HomeProvider>(context, listen: false)
    .addNewMessage(Message.fromJson(data)));
    }

    Bu konularda fikir verebilirseniz sevinirim.

    muratapps Buradaki sorun şu gibi;
    Stream tanımı yapmışsın ve sayfaya ilk girişte stream socket’i dinliyor. Mesaj geldiğinde ekrana yazdırıyorsun sanırım.
    Ama sayfa kapanırken socket’i kapatmamışsın ve dinlemeye devam ediyor. Mesaj geldiğinde sayfa kapatıldığı için “This widget has been unmounted” hatası alıyorsun. 2. durum da socket açık kaldı arka planda ve sen sayfaya tekrar girdin. Tekrar socket tanımı yapmaya çalıştı. Bu hata verir mi emin olamadım ama paralelde 2 bağlantı açmış oldu.
    Çözüm de hatada verilmiş zaten. Ya widget’i geri ver yada socket’i dispose et. Burada yapman gereken sayfa kapanırken _socket.Close(); veya _socket.Dispose(); gibi bir metod çağırman. Filtreleme için query kullanabilirsin. Flutter tarafında Socket tanımı yaparken transports verdiğin gibi query de verebiliyor olman lazım. query de sender ve receiver id gönderip nodeJS tarafında filtreleyebilirsin.

    HseyinAkkaya socket.dispose() yaptığım zaman tekrar bir mesajlaşma sayfasına girdiğim zaman _socket.on(
    'message',
    (data) => Provider.of<HomeProvider>(context, listen: false)
    .addNewMessage(Message.fromJson(data)));
    }
    bu kısım çalışmıyor yani node js tarafına veri gitmiyor onu çözemedim. Onun haricinde socket.dispose yapmadığım zaman da o hatayı alıyorum. Query tarafında şöyle bir yol izledim ancak yine de tüm data geliyor belki queryi yanlış yazmış olabilirim.

    `socket.on('message', (data) => {
        db.query("select * from rooms WHERE(sender_id = ? OR sender_id = ?) AND ( receiver_id = ? OR receiver_id = ?)",
          [senderId, receiverId, senderId, receiverId], 
          (err, result) => {
            if (result[0] != null) {
              // query doğru ve boş değilse mesajlar uygulamaya push edilecek
            } else {
              // ilk defa mesaj gönderiliyorsa sender ve receiver arasında bağlantı kurulacak
              sentAt = Date.now()
              db.query(
                "INSERT INTO rooms (sender_id,receiver_id,token) VALUES (?,?,?)",
                [senderId, receiverId, senderId+receiverId+sentAt],
                (err, result) => {
                  if (err) {
                    console.log(err)
                  } else {
                    // bağlantı kurulduktan sonra mesajlar uygulamaya push edilecek
                    sendMessage(data.message, senderId, receiverId, senderId+receiverId+sentAt)
                  }
                }
              );
            }
        });
      })`

    Aslında getMessage fonksiyonum doğru çalışıyor yani bir mesaja tıklandığında o kişi ile olan mesaj kayıtları geliyor sadece ama o an bir yazı yazıp mesaj gönderdiği zaman başka bir kullanıcının gözünden o mesajı görebiliyorum.


    `function sendMessage(msg, senderId, receiverId, token) {
      db.query(
        "INSERT INTO messages (message,sender_id,receiver_id,token) VALUES (?,?,?,?)",
        [msg, senderId, receiverId, token],
        (err, result) => {
          if (err) {
            console.log(err)
          } else {
            const message = {
              message: msg,
              senderId: senderId,
              receiverId: receiverId,
              sentAt: Date.now()
            }
            console.log(message)
    
            messages.push(message)
            io.emit('message', message)
          }
        }
      );
    }`

    Bu arada flutter tarafında dediğiniz gibi query methoduyla sender ve receiver id leri gönderiyorum node tarafında da buna göre sorgulama yapıyorum eğer koşullar doğru ise mesajları push ediyorum ama galiba uygulama tarafında da ekstra bir filtreme yapmam gerekiyor veya uygulama tarafında filtreleme yapmak doğru bir yaklaşım mı yani tüm datayı uygulamaya gönderip filtrelemek güvenlik açığı yaratabilir mi bilemedim

    `IO.OptionBuilder().setTransports(['websocket']).setQuery({
            'senderId': widget.senderId,
            'receiverId': widget.receiverId
          }).build(),`

      Şu ana kadar filtrelemeyi başardım, sadece o kişiye iletiliyor mesajlar ancak bu bir üstteki mesajda belirttiğim hata devam ediyor.

      @override
        void initState() {
          _socket = IO.io(
            Platform.isIOS ? 'http://localhost:3000' : 'http://10.0.2.2:3000',
            IO.OptionBuilder().setTransports(['websocket']).setQuery({
              'senderId': widget.senderId,
              'receiverId': widget.receiverId
            }).build(),
          );
          _connectSocket();
      
          super.initState();
        }
      
        @override
        void dispose() {
          _messageInputController.dispose();
      
          super.dispose();
        }
      
        _sendMessage() {
          _socket.emit('message', {
            'message': _messageInputController.text.trim(),
            'senderId': widget.senderId,
            'receiverId': widget.receiverId,
          });
      
          Provider.of<HomeProvider>(context, listen: false)
              .addNewMessage(Message.fromJson({
            'message': _messageInputController.text.trim(),
            'senderId': widget.senderId,
            'receiverId': widget.receiverId,
            'sentAt': 1706110401228
          }));
      
          _messageInputController.clear();
        }
      
        _connectSocket() {
          _socket.onConnect((data) => print('Connection established'));
          _socket.onConnectError((data) => print('Connect Error: $data'));
          _socket.onDisconnect((data) => print('Socket.IO server disconnected'));
          _socket.on(
              'message',
              (data) => Provider.of<HomeProvider>(context, listen: false)
                  .addNewMessage(Message.fromJson(data)));
        }

      Kodlar bu şekilde uygulama ilk defa açılıp mesaj atacağınız kişiye tıklandığında sorun yok mesaj gönderip alabiliyorsunuz ancak bir geri sayfaya gidip başka bir kişiye tıkladığınız da önceki mesajlar dahil hiç bir veri gelmiyor ve mesaj göndermeye bastığınız da node tarafına veri iletilmiyor. _sendMessage fonksiyonu tetikleniyor ancak servera veri gitmiyor yani emit fonksiyonu çalışmıyor.

      dispose fonksiyonuna _socket.dispose(); yazdığımda ise mesaj göndermeye bastığım anda

      Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
      E/flutter ( 4767): Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.

      Bu hatayı alıyorum bunu çözebilirsem chat sistemimi kullanabileceğim

      muratapps _socket oluşturulurken forceNew parametresini true set edip nodejs tarafında

      socket.on('disconnect', function() {
      // handle disconnect
      socket.disconnect();
      socket.close();
      });

      yapmayı deneyin bir de

      Write a Reply...