Node.js 如何将WebSockets和Socket.IO与flatter一起使用?

Node.js 如何将WebSockets和Socket.IO与flatter一起使用?,node.js,flutter,dart,websocket,socket.io,Node.js,Flutter,Dart,Websocket,Socket.io,我一直在尝试使用sockets将我的flatter应用程序与node js服务器集成,我使用WebSockets作为flatter部分,Socket.io作为nodejs部分,并制作一个服务器将其连接到flatter客户端 const express= require('express'); const app= express(); const http=require('http'); const socketio= require('socket.io'); const server= h

我一直在尝试使用sockets将我的flatter应用程序与node js服务器集成,我使用WebSockets作为flatter部分,Socket.io作为nodejs部分,并制作一个服务器将其连接到flatter客户端

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'));
我在3000端口上创建了一个服务器,现在我想使用颤振客户端与这个服务器通信

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();
  }
}
导入“包:flift/foundation.dart”;
导入“package:web_socket_channel/io.dart”;
进口“包装:颤振/材料.省道”;
导入“package:web_socket_channel/web_socket_channel.dart”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
最终标题=‘WebSocket演示’;
返回材料PP(
标题:标题,,
主页:我的主页(
标题:标题,,
频道:IOWebSocketChannel.connect('ws://localhost:3000'),
),
);
}
}
类MyHomePage扩展StatefulWidget{
最后的字符串标题;
最终WebSocketChannel通道;
MyHomePage({Key,@required this.title,@required this.channel})
:super(key:key);
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
TextEditingController _controller=TextEditingController();
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
主体:填充物(
填充:常数边集全部(20.0),
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
形式(
子项:TextFormField(
控制器:_控制器,
装饰:输入装饰(标签文本:“发送消息”),
),
),
StreamBuilder(
流:widget.channel.stream,
生成器:(上下文,快照){
返回填充(
填充:常量边集。对称(垂直:24.0),
子项:文本(snapshot.hasData?${snapshot.data}:“”),
);
},
)
],
),
),
浮动操作按钮:浮动操作按钮(
onPressed:\u发送消息,
工具提示:“发送消息”,
子:图标(Icons.send),
),//此尾随逗号使生成方法的自动格式设置更方便。
);
}
void_sendMessage(){
if(_controller.text.isNotEmpty){
widget.channel.sink.add(_controller.text);
}
}
@凌驾
无效处置(){
widget.channel.sink.close();
super.dispose();
}
}
在这些之后,当我试图发送一条信息并将其取回时,我无法做到这一点。我真的认为这应该行得通。如果不是,应该怎么做?这里真的需要帮助。
谢谢

你不能真的那样做。Websocket和socket.io不同。Socket.io写在顶部websocket上。然而,它编写了代码,以便可以回退到其他通信方法,如长轮询或多部分流。为此,socket.io向每个数据包添加额外的元数据。由于socket io客户端不能与websocket服务器一起工作,而websocket客户端不能与socket io服务器一起工作

socket io文档在其第一页解释了为什么您不能这样做:

下面是另一篇解释差异的好帖子:

你不能真的那样做。Websocket和socket.io不同。Socket.io写在顶部websocket上。然而,它编写了代码,以便可以回退到其他通信方法,如长轮询或多部分流。为此,socket.io向每个数据包添加额外的元数据。由于socket io客户端不能与websocket服务器一起工作,而websocket客户端不能与socket io服务器一起工作

socket io文档在其第一页解释了为什么您不能这样做:

下面是另一篇解释差异的好帖子:

我有socket.io服务器和带有flatter的应用程序

我建议使用express
4.17.1
和socket.io
2.3.0
服务器端

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 ');
    });
});

这将在包的pubspec.yaml中添加这样的行

dependencies:
  socket_io_client: ^0.9.12
现在,在Dart代码中,您可以使用:

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();
}
}
import'包:socket\u io\u client/socket\u io\u client.dart'作为io;
类_MyHomePageState扩展状态{
IO.插座;
字符串userid=“”;
@凌驾
void initState(){
//IO.插座;
套接字=IO.IO(
'http://192.168.0.12:3000',
{
“传输”:['websocket']
},
);
socket.onConnect((数据){
日志(“连接”);
userid=socket.id;
日志(id:+userid);
socket.on('carrito:all',(数据){
日志(“mensaje:+data.toString());
});
});
//emit('carrito:all',{'id':userid});
socket.on('carrito:all',(数据){
日志(“消息”+数据.toString());
});
socket.connect();
super.initState();
}
}

我有socket.io服务器和带有flatter的应用程序

我建议使用express
4.17.1
和socket.io
2.3.0
服务器端

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 ');
    });
});

这将在包的pubspec.yaml中添加这样的行

dependencies:
  socket_io_client: ^0.9.12
现在,在Dart代码中,您可以使用:

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();
}
}
import'包:socket\u io\u client/socket\u io\u client.dart'作为io;
类_MyHomePageState扩展状态{
IO.插座;
字符串userid=“”;
@凌驾
void initState(){
//IO.插座;
套接字=IO.IO(
'http://192.168.0.12:3000',
{
“传输”:['websocket']
},
);
socket.onConnect((数据){
日志(“连接”);
userid=socket.id;
日志(id:+userid);
socket.on('carrito:all',(数据){
日志(“mensaje:+data.toString());
});
});
//emit('carrito:all',{'id':userid});
socket.on('carrito:all',(数据){
日志(“消息”+数据.toString());
});
socket.connect();
super.initState();
}
}

这里有哪些替代方案?您可以使用websocket或socket io。您必须选择一个。如果我为节点选择Socket.io,将使用哪个库