Flutter Channel ile iOS ve Android Kodu Çağırmak + Native SocketIO Client Framework İle Kullanımı

Gökhan Alp
Flutter Türkiye
Published in
11 min readApr 17, 2020

Merhaba, bu yazıda Flutter’da Channel kullanılarak nasıl iOS ve Android kod çağrılacağını ve Flutter’a nasıl bilgi gönderileceğini paylaşacağım. Örnekte SocketIO Client’ın iOS ve Android kütüphaneleri kullanılacaktır bu sayede Flutterda olmayan ancak native yazılmış kütüphanelerin nasıl kullanılabileceğini görmüş olacaksınız.

Anlatım 3 bölüme ayrılacaktır. Bu bölümler Flutter, iOS ve Android olacaktır. Flutter projesi iki farklı platformun ortak iletişim kurduğu katman olacak ve diğer platformlarda nasıl iletişim kurulduğuna değinilecektir.

Örnek projemiz basit bir chat uygulaması örneğidir. NodeJS ile yazılmış ve SocketIO ile iletişim kurmaktadır. Örnek basitçe bağlantı kurma (connect), bağlantı koparma (disconnect) ve mesaj gönderme ile mesaj çekme özelliklerine sahip olacaktır. Flutter iOS ve Android ile “SocketIOClient” kanalı üzerinden iletişim kuracaktır.

Aşağıdaki grafik bu örnekte Flutter Method Channel ile iletişimin nasıl olacağını göstermektedir;

Flutter

Öncelikle bir MethodChannel nesnesi yaratıp bunu tutuyoruz. Örnekte bu nesneyi State classı içinde tutup kullandım.

MethodChannel channel = MethodChannel('SocketIOClient');

Uygulamımızdaki UI’ında kullanılmak üzere alttaki değişkenleri de ekliyoruz. messages değişkeninde ekrana basılacak mesajlar tutulacak, isConnected eğer bağlantı bilgisini tutacak, senderName en son belirlenen kullanıcı ismini tutacak ve messageTextController ise UI’daki mesaj göndermemizi sağlayan TextField’a ait bilgileri çekip setlememize yarayacak.

List<String> messages = List<String>();
bool isConnected = false;
String senderName = "user";
final messageTextController = TextEditingController();

Bir initState metodu ile sayfa ilk açıldığında bazı şeylerin aktif olmasını sağlayalım. Burada senderName değişkenindeki String text’in sonuna random bir numara ekledik, böylece kullanıcı isimleri ayrıştırılmış oldu. checkFlutterChannel metodunu Channel iletişimini basit bir yolla kurup kurmadığımızı test etmek için, setupMetodCallHandlers metodunu ise Flutter’a iOS ve Android’den gelen bilgileri handle etmek için kullanacağız.

@override
void initState() {
super.initState();
checkFlutterChanel();
int userNo = new Random().nextInt(100);
senderName = senderName + userNo.toString();
setupMetodCallHandlers();
}

Flutter ile iOS’un yada Android kodun iletişim kurup kurmadığını denemek için basit bir örnek yapalım. Örnekte “flutterChannelTest” aynı isimde native projede barındırılmış bir metoda gidecek ve karşılığında bir bool dönüş yapacaktır. Bu metoda giderken iletişimi test etmek amaçlı içinde “arg” anahtarı ve “test” değeri bulunan bir dictionary göndereceğiz. Eğer bilgi bu şekilde giderse true gitmez ise false dönüşü yapacak.

void checkFlutterChanel() {
Future<bool> result = channel.invokeMethod('flutterChannelTest',<String, String> {
'arg': 'test'
});
result.then((boolVal) {
if (boolVal == true) {
setState(() {
this.messages.add("Flutter Channel Test Başarılı");
});
} else {
setState(() {
this.messages.add("Flutter Channel Test Başarısız");
});
}
});
}

Flutter’dan iOS ve Android metodlarını çağırmak ve bilgi göndermek için channel nesnesinin invokeMethod isimli metodlarını kullanacağız.

Flutter ile bağlantı kurmak için connect’i bağlantıyı koparmak için disconnect’i çağıracağız. Bunu örnekte bir tuşa bastıktan sonra çağırabilmek kodlarını metod içine yazarak tetiklenmesini sağlıyorum. Karşılığında bir değer beklemiyor olacağız çünkü işlem async olarak çalışacağından dönüşlerini farklı şekilde dinleyerek elde edeceğiz.

void connect() {
channel.invokeMethod('connect');
}
void disconnect() {
channel.invokeMethod('disconnect');
}

Mesaj gönderimi için sendMessage isimli metodu kullanacağız ve parametre olarak sender (gönderen) ve message (mesaj) isimli iki tane bilgiyi dictionary olarak metoda göndereceğiz.

void sendMessage(String message) {
if(message != null && message.length > 0) {
channel.invokeMethod('sendMessage',<String, String> {
'message': message,
'sender': this.senderName
});
setState(() {
this.messageTextController.text = "";
});
}
}

Şimdi gelelim Flutter’a nasıl bilgi göndereceğimize yani Flutter’a iletilen bilgileri nasıl dinleyeceğimiz konusuna. Bunun için setMethodCallHandler kullanacağız. Aşağıdaki örneklerde bağlantı kurma, bağlantı kopma ve mesaj gelmesi durumunda Flutter’a dönen bilgiler paylaşılacaktır.

Örnekte connected ve disconnected metodları bir bilgi dönmeyecek ama messageReceived metodunda sender (gönderen) ve message (mesaj) bilgisileri String List kullanılarak dönecektir.

Örnekte SocketIO dönüşü ve bizim Flutter’a döndüğümüz metot isim karşılıkları şöyledir:
connect -> connected
disconnect -> disconnected
message -> messageReceived

Dikkat: Başka bir sayfaya geçildiğinde ve dönüldüğünde handlers tekrar çalışmamaktadır. Bu durumda isteseniz sayfaya dönüldüğünde veya başka bir yerden tetiklendiğinde setupMetodCallHandlers metodunu tekrar çağırarak handler’ın tekrardan setlenmesini sağlayarak çalışmasını sağlayabilirsiniz ya da başka bir yolla bu durumu giderebilirsiniz.

void setupMetodCallHandlers() {
Future<dynamic> handlers(MethodCall methodCall) async {
switch (methodCall.method) {
case 'connected':
print('Bağlandı');
setState(() {
this.isConnected = true;
this.messages.add('Bağlandı');
});
return;
case 'disconnected':
print('Bağlantı koptu');
setState(() {
this.isConnected = false;
this.messages.add('Bağlantı Koptu');
});
return;
case 'messageReceived':
List args = methodCall.arguments as List;
String sender = args[0] as String;
String message = args[1] as String;
print(sender + ' kullanıcısından mesaj geldi: ' + message);
setState(() {
this.messages.add(sender + ': ' + message);
});
return;
default:
return;
}
}

channel.setMethodCallHandler(handlers);
}

Flutter’da hepsi bu kadar. iOS ve Android anlatımına geçmeden önce sayfanın UI kodlarını da altta paylaşıyorum.

@override
Widget build(BuildContext context) {

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: Column(
children: <Widget>[
Container(
width: 200,
height: 50,
child: FlatButton(
child: Text(this.isConnected ? 'Disconnect' : 'Connect', style: TextStyle(color: Colors.black, fontSize: 20)),
onPressed: (){
if(this.isConnected) {
disconnect();
} else {
connect();
}
},
),
),
Expanded(
child: Container(
color: Colors.grey[300],
child: ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: messages.length,
itemBuilder: (BuildContext context, int index) {
return Container(
color: index % 2 == 0 ?
Colors.blue : Colors.red,
child: Text(messages[index],
textAlign: TextAlign.left,
style: TextStyle(fontSize: 15)),
);
}
),
),
),
SafeArea(
bottom: true,
child: Container(
width: double.infinity,
height: 50,
child: Row(
children: <Widget>[
Expanded(
child: TextField(
controller: this.messageTextController,
style: TextStyle(color: Colors.black),
decoration: InputDecoration(
border: OutlineInputBorder()
),
),
),
Container(
color: Colors.green,
child: FlatButton(
child: Text("Gönder",
style: TextStyle(color: Colors.white)),
onPressed: () {
sendMessage(this.messageTextController.value.text);
},
),
)
],
),

),
)
],
)
)
);
}

iOS

Şimdi sıra iOS tarafında… Buradaki yapılcak geliştirmeyi Xcode’da yapıp, eğer Flutter kodlarını da yazıp çalıştırdıysanız iOS tarafı geliştirme tamamlanana kadar burda çalıştırıp test etmenizi tavsiye ederim.

Eğer harici bir kütüphane eklemekle ilgilenmiyor ve sadece Channel ile ilgileniyorsanız bu konuyla alakalı anlatımları pas geçebilirsiniz. Eğer ilgileniyorsanız ilk olarak SocketIO Client kütüphanesini pod kullanarak iOS’a eklemekle başlayalım.

Eğer Flutter run ettiğinizde pod dosyası oluşmamışsa ilk etapta pod dosyası oluşturmamız gerekmektedir. Pod dosyası projenizin ana klasöründe iOS klasörü altında barındırılır. Varsa bu adımı atlayın, yoksa terminalden bu klasör dizinine gidin ve şu komutu çalıştırın;

pod init

Belirttiğim klasörde Podfile isimli bir dosya mevcut olacak içini açın.
target ‘Runner’ do içinde alttaki kodu yazın. Flutter’dan bazı paketler indirdiyseniz Podfile dosyanız çok karmaşık olacaktır. Bu durumda dosyada aratma yapın ve “# Plugin Pods” yazan yerin altına aşağıdaki kodları ekleyin. Not: Bu yer tahminen sizde de pod ‘Flutter’, :path => ‘Flutter’ kodunun altına tekabül edecektir.

# Plugin Pods
pod 'Socket.IO-Client-Swift', '~> 15.2.0'

Ardından podun indirilmesini sağlayalım.

pod install

Kütüphanenin pod ile inmiş olması gerekmektedir. Başarılı bir şekilde indirdiysek sürecimize devam edelim. Web iletişimi yapabilmek için izin vermemiz gerekecektir. Info.plist’e sağ tıklayarak Open As Source Code şeklinde açıp şunu ekleyelim:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

Uygulamanın Flutter aracılığıyla açık olmadığından emin olalım, açıksa kapatalım. Sonra ilk olarak clean edip Xcode’da bir kodu çalıştırmaya çalışalım. Eğer hata alırsak endişe etmeyin bu sefer Flutter’da kodu çalıştırın çalıştırdıktan sonra durdurup Xcode’a geçip tekrar Clean edip tekrar çalıştırın.

Şimdi SocketIOClient isimli bir class dosyası yaratalım. SocketIO ile ilgili kodları buraya koyacağız. SocketIO’yu import edelim. Class’ı shared’da tutup manager değişkeninde SocketManager’ı tutalım. Örneğimizde 3000 portunu kullandık ve local olarak çalıştırdık bu sebepten adres olarak “http://localhost:3000" kullanıldı.

SocketIOClient.swift

import SocketIOclass SocketIOClient {
static let shared = SocketIOClient()
let manager = SocketManager(
socketURL: URL(string: "http://localhost:3000")!,
config: [.log(true), .compress])

Flutter kod örneğinde bir flutterChannelTest örneğinden bahsetmiştik. Flutter ile iOS iletişime geçip geçmediğini anlamak için basit bir örnek olarak iOS tarafı kodunu da buraya ekleyelim.

static func flutterChannelTest(arg: String) -> Bool {
print(“iOS flutterChannelTest arg: \(arg)”)
return arg == “test” ? true : false
}

Şimdi SocketIO’ile bize ulaşan mesajları yönetmek için init() içinde eventları dinleyip aksiyon alan kodları yazalım. manager.defaultSocket.on SocketIO’ya gelen eventlar’ı dinleyecek flutterchannel.invokeMethod iOS’dan Flutter’a bilgilerin gitmesini sağlayacaktır. Flutter Channel’a ait invokeMethod’da ilk parametre Flutter tarafındaki hedef metod karşılığıdır, arguments ise gönderilecek parametrelere yani bilgilere tekabül eder.

init() {
self.manager.defaultSocket.on(clientEvent: .connect)
{ (data, ack) in
if let flutterchannel = (UIApplication.shared.delegate as?
AppDelegate)?.flutterchannel {
flutterchannel.invokeMethod("connected", arguments: nil)
}
}
self.manager.defaultSocket.on(clientEvent: .disconnect)
{ (data, ack) in
if let flutterchannel = (UIApplication.shared.delegate as?
AppDelegate)?.flutterchannel {
flutterchannel.invokeMethod("disconnected", arguments: nil)
}
}
self.manager.defaultSocket.on("message")
{ (data, ack) in
if data.count > 1, let sender = data[0] as? String,
let message = data[1] as? String {
if let flutterchannel = (UIApplication.shared.delegate as?
AppDelegate)?.flutterchannel {
flutterchannel.invokeMethod("messageReceived",
arguments: [sender, message])
}
}
}
}

Ardından Flutter’dan iOS’a giden tarafı yapalım. Flutter tarafından connect, disconnect ve sendMessage gibi metodları çağırmıştık hatırlarsanız. Bunlara ait kodlarda aşağıdadır;

func connect() {
self.manager.defaultSocket.connect()
}
func disconnect() {
self.manager.defaultSocket.disconnect()
}
func sendMessage(sender: String, message: String) {
self.manager.defaultSocket.emit("sendMessage", sender, message) {
print("SocketIO \(sender) tarafından şu mesaj gönderildi: \(message)")
}
}

Şimdi asıl iletişimin kurulduğu yere geçelim. Burası AppDelegate’dir. İlk olarak burada değişkenleri tutalım.

let socketIOClient = SocketIOClient.shared
var flutterchannel: FlutterMethodChannel?

Daha sonra didFinishLaunchingWithOptions’ta Channel’ı setleyip Flutter’dan gelen çağırımları SocketIOClient’a yönlendiren kodları da setMethodCallHandler içine yazalım. setMethodCallHandler Flutter metod çağrımlarını dinleyerek işin yapılmasını sağlayacaktır. Burada call parametresinde Fluterdan gelen parametreleri call.arguments sayesinde elde edebilmekteyiz.

AppDelegate.swift

override func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
if let controller = self.window.rootViewController as? FlutterViewController {

self.flutterchannel = FlutterMethodChannel(name: "SocketIOClient", binaryMessenger: controller.binaryMessenger)

self.flutterchannel?.setMethodCallHandler { (call, result) in
if call.method == "flutterChannelTest",
let args = call.arguments as? [String: Any] {
if let arg = args["arg"] as? String {
let resultChannel =
SocketIOClient.flutterChannelTest(arg: arg)
result(resultChannel)
}
} else if call.method == "connect" {
SocketIOClient.shared.connect()
} else if call.method == "disconnect" {
SocketIOClient.shared.disconnect()
} else if call.method == "sendMessage",
let args = call.arguments as? [String: Any],
let sender = args["sender"] as? String,
let message = args["message"] as? String {
SocketIOClient.shared.sendMessage(sender: sender,
message: message)
}
}
}

GeneratedPluginRegistrant.register(with: self)
return super.application(application,
didFinishLaunchingWithOptions: launchOptions)
}

Android

Evet sıra Android projemizde. Android Studio kullanıyorsanız Flutter projenizde android/app/build.gradle konumuna gelin sağ üstte Open for Editing in Android Studio tuşunu göreceksiniz. Tıklayın böylece karşımıza sadece Android projesi açılmış yeni bir proje gelecektir. Android tarafındaki geliştirmeyi bu şekilde Flutter’dan izole olarak yapıp testlerini de bu şekilde sürdürelim. Farklı bir yöntemle Android projesi olarak da açabilirsiniz Android kısmını yöntem size kalmış.

Eğer kütüphane eklemekle ilgilenmiyorsanız gradle kullanarak SocketIO Client kütüphanesi konusuyla alakalı anlatımları pas geçebilirsiniz. Eğer ilgileniyorsanız devam eden anlatımdaki adımları uygulayın.

build.gradle (Module: app) ‘i açalım. En alttaki dependencies’e alttaki kodu ekleyelim. Sonra gradle’ı sync edelim.

implementation ('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}

SocketIO iletişim kurabilmesi için networkSecurityConfig tanımlamamız ve internet iletişimine izin vermemiz gerekmektedir. Bunun için ilk etapta res/xml konumuna network_security_config.xml dosyası oluşturalım ve içini aşağıdaki şekilde dolduralım.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

AndroidManifest.xml içine internet permission ve networkSecurityConfig’i ekleyelim.

<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...

Simdi SocketIOClient classı oluşturalım. İçinde shared’de gene sınıfın kendini ayrıca SocketIO yönetimini yapmak için socket değişkenini, Flutter ile iletişim kurmak için flutterchannel değişkenini ve UI thread’de kod çalıştırmamız gerektiğinden Activity değeri barındıran activity değişkenini ekleyelim.

SocketIOClient.java

public class SocketIOClient {
static SocketIOClient shared = new SocketIOClient();
Socket socket;
MethodChannel flutterchannel;
Activity activity;
...

Ardından sınıfın constructor’ını oluşturuyoruz ve burada ilk etapta socket değişkenin oluşmasını sağlıyoruz. Burda url kısmına özellikle dikkatinizi çekmek istiyorum. iOS’ta localhost olarak tanımladığımızda sorun olmamıştı lakin Android’de bu şekilde ulaşamıyoruz. Hatta 127.0.01 yazsak bile ulaşamıyoruz. Geliştirmeyi Android AVD emulatörlerinden yaptığım için emulatörde 127.0.0.1 ‘e tekabül eden 10.0.2.2 adresini verdim.

AVD için: 10.0.2.2
Genymotion için: 10.0.2.3

SocketIOClient() {
try {
String url = "http://10.0.2.2:3000";
URI uri = new URI(url);
socket = IO.socket(uri);
} catch (Exception e) {
Log.v("SocketIOManager", "Socket setleme başarısız");
}
...

SocketIO’dan gelen eventleri dinleyen listener’ları bu constructor içine aynı şekilde ekleyeceğiz. Örnekte connect ve disconnect herhangi bir paremetre almazken “message” isimli event parametre almış ve göndermiştir. SocketIO’dan gelen bilgiler Flutter’a invokeMethod metodu üzerinden dönülmüştür. invokeMethod içindeki kodlara birazdan değineceğiz. Alttaki örnek SocketIO’ya ulaşan eventlerin Android’den Flutter’a gönderilmesini göstermektedir.

    ...
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
invokeMethod("connected", null);
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
invokeMethod("disconnected", null);
}
}).on("message", new Emitter.Listener() {

@Override
public void call(Object... args) {
if (args.length == 2) {
String sender = (String) args[0];
String mesage = (String) args[1];
if(sender != null && mesage != null) {
ArrayList<String> params = new ArrayList<String>();
params.add(sender);
params.add(mesage);
invokeMethod("messageReceived", params);

}
}
}
});
}

Android tarafında SocketIO’ya gelen event başka bir thread üzerinden çalışan metoda düşmektedir ancak Flutter’a bilgi gönderceğimiz zaman yani Flutter Channel’daki invokeMethod’u çağırcağımız zaman işlemin UI thread üzerinde çalışması gerekmektedir. Bunu pratik bir şekilde sağlamak için ortaklaşa kullanılacak aynı isimde ancak bu sınıfta kullanılan bir private metot oluşturdum.

private void invokeMethod(@NonNull String method, @Nullable Object arguments) {
if (flutterchannel != null && activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
flutterchannel.invokeMethod(method, arguments);
}
});
}
}

Pratik bir şekilde deneme yapmak amacıyla flutterChannelTest isimli bir metot oluşturdum. Bu metot diğerlerinden farklı olarak SocketIO ile iletişim kurmuyor ancak sınıfın ve içindeki metotun doğru bir şekilde çalışıp çalışmadığını teyit amaçlı kullanılmakta ve doğrudan bir değer dönmektedir.

static boolean flutterChannelTest(String arg) {
Log.v("SocketIO", "Android flutterChannelTest arg: " + arg);
return arg == "test" ? true : false;
}

Şimdi sırada Flutter’dan Android’deki çağıralacak metotları yazmaya geldi. Aşağıdaki örnekte connect, disconnect ve sendMessage’e ait kodlar paylaşılmıştır.

void connect() {
socket.connect();
}

void disconnect() {
socket.connect();
}

void sendMessage(String sender, String message) {
socket.emit("sendMessage", sender, message, new Ack() {
@Override
public void call(Object... args) {
Log.v("SocketIO", "SocketIO " + sender + " tarafından şu mesaj gönderildi: " + message);
}
});
}

Evet şimdi sırada SocketIOClient sınıfının activity ve flutterchannel gibi bilgilerini setleyen ve uygulamamızın Flutter sayfasını barındıran MainActivity’e değinmeye geldi. Burada Flutter’dan Android’e gidiş akışını sağlayacağız. Flutter’dan çağırdığımız metodlar ve ilgili parametreleri ilk olarak buraya düşecektir.

İlk olarak socketIOClient ve flutterchannel nesnelerini tutalım ve bunların sağlıklı oluşmasını veya setlenmesini sağlayalım.

MainActivity.java

public class MainActivity extends FlutterActivity {
SocketIOClient socketIOClient = SocketIOClient.shared;
MethodChannel flutterchannel = null;

@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
flutterchannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "SocketIOClient");
socketIOClient.flutterchannel = flutterchannel;
socketIOClient.activity = this;
...

Şimdi sırada Flutter’dan Android’deki SocketIOClient sınıfı içindeki metotların çağırılmasına geldi. Bunun için setMethodCallHandler kullanacağız. Flutter’ın gitmek istediği metotları call.method bilgisinden, parametrelerini ise call.arguments üzerinden elde etmekteyiz. Eğer gittiğimiz metot bir bilgi dönüyorsa bu bilgiyi Flutter’a iletmek için result’ı kullanıyoruz. Aşağıdaki örnekte sadece flutterChannelTest Flutter’a result dönmüştür.

...
flutterchannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("flutterChannelTest")) {
HashMap<String,String> map = (HashMap<String,String>) call.arguments;
if (map != null) {
String arg = map.get("arg");
boolean resultChannel = SocketIOClient.flutterChannelTest(arg);
result.success(resultChannel);
}
} else if (call.method.equals("connect")) {
socketIOClient.connect();
} else if (call.method.equals("disconnect")) {
socketIOClient.disconnect();
} else if (call.method.equals("sendMessage")) {
HashMap<String, String> map = (HashMap<String,String>) call.arguments;
if (map != null) {
String sender = map.get("sender");
String message = map.get("message");
if(sender != null && message != null) {
socketIOClient.sendMessage(sender, message);
}
}
}
}
});
}
}

Evet hepsi bu kadar. Aslında Flutter Channel kullanımı aşırı derecede basittir. Channel kullanarak Flutter’da olmayan native kütüphaneleri veya native kodları bu yolla kullanabilirsiniz.

Kaynak Kod

Projeye ait kodları GitHub üzerinden indirebilirsiniz.

Flutter:

NodeJS:

Ekstra

NodeJs’teki kodu da aşağıda paylaşacağım. Express ve Socket.io ‘yu indirmeniz gerekecektir. İndirmek için alttaki kodları terminalden sırayla yazmanız gereklidir;

npm install express
npm install socket.io

index.js içineki kodlar:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;

io.on('connection', function(socket){
console.log('User connected to chat with connection id: ', socket.client.conn.id);

socket.on('disconnect', function(){
console.log('User disconnected to chat with connection id: ', socket.client.conn.id);
});

socket.on('sendMessage', function(sender, message){
console.log(String('Sender ' + sender + ' sent message: ' + message));
io.emit('message', sender, message);
});

});

exports.app = http.listen(port, function(){
console.log('listening on *:' + port);
});

Umarım yazım faydalı olmuştur. Faydalı bulmanız halinde alkışlarınızı beklerim. Ayrıca yorumlarınızla fikirlerinizi paylaşmanızdan memnun olurum.

Teşekkürler!

--

--