I have been trying to integrate my flutter app with a node js server using sockets and I am using WebSockets for the flutter part and Socket.io for the nodejs part and making a server to connect it to the flutter client.
const express= require('express');
const app= express();
const http=require('http');
const socketio= require('socket.io');
const server= http.createServer(app);
const io=socketio(server);
app.get('/',(req,res)=>{
res.send('hey people')
})
const PORT= process.env.PORT||3000;
io.on('connection', (socket) => {
console.log('a user connected');
});
server.listen(PORT,()=> console.log('app started'));
I created a server on 3000 port here and now I want to communicate with this server using flutter client side.
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
import 'package:flutter/material.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = 'WebSocket Demo';
return MaterialApp(
title: title,
home: MyHomePage(
title: title,
channel: IOWebSocketChannel.connect('ws://localhost:3000'),
),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
final WebSocketChannel channel;
MyHomePage({Key key, @required this.title, @required this.channel})
: super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Form(
child: TextFormField(
controller: _controller,
decoration: InputDecoration(labelText: 'Send a message'),
),
),
StreamBuilder(
stream: widget.channel.stream,
builder: (context, snapshot) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
child: Text(snapshot.hasData ? '${snapshot.data}' : ''),
);
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: Icon(Icons.send),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
widget.channel.sink.add(_controller.text);
}
}
@override
void dispose() {
widget.channel.sink.close();
super.dispose();
}
}
After these when I am trying to send a message and get it back, I am not able to do it. I really think this should work. If not What should? Really need some help here. Thanks!
You can't really do that. Websocket and socket.io is different. Socket.io is written on top websocket. However, it has code written so that it's ready to fallback to other communication methods like long polling or multipart stream. In order to do that socket.io adds additional metadata to each packet. And because of that socket io client won't work with websocket server while websocket client won't work with socket io server.
The socket io doc explains why you can't do that on its first page: https://socket.io/docs/
Here is another good posts explaining the difference: https://www.hackdoor.io/articles/6xQkgQo4/differences-between-websockets-and-socketio
I have the socket.io server and the app with flutter
I recommend using express 4.17.1
and socket.io 2.3.0
server side
const patch=require('path');
const express=require('express');
const app=express();
const socketIO=require('socket.io');
//setting
app.set('port', process.env.PORT || 3000);
//static file
app.use(express.static(patch.join(__dirname,'public')))
console.log(patch.join(__dirname,'public'));
//start server
const server=app.listen(app.get('port'), () => {
console.log('servidor en el puerto ', app.get('port'));
});
//socketIO
const io=socketIO(server);
io.on('connection', function(socket) {
id=socket.id;
console.log('new connection ',id);
socket.on('carrito:all',function(data) {
console.log("todo disp "+data);
})
socket.on('admin:user',function(data) {
console.log("res login ");
})
socket.on('disconnect', function(){
console.log('user '+socket.id+' disconnected ');
});
});
https://pub.dev/packages/socket_io_client/versions/0.9.12
This will add a line like this to your package's pubspec.yaml
dependencies:
socket_io_client: ^0.9.12
Now in your Dart code, you can use:
import 'package:socket_io_client/socket_io_client.dart' as IO;
class _MyHomePageState extends State<MyHomePage>{
IO.Socket socket;
String userid="";
@override
void initState() {
//IO.Socket socket;
socket = IO.io(
'http://192.168.0.12:3000',
<String, dynamic>{
'transports': ['websocket']
},
);
socket.onConnect((data){
log('connect');
userid=socket.id;
log("id: "+userid);
socket.on('carrito:all', (data){
log("mensaje: "+data.toString());
});
});
//socket.emit('carrito:all', {'id': userid});
socket.on('carrito:all', (data){
log("message "+data.toString());
});
socket.connect();
super.initState();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With