【问题标题】:How to use WebSockets and Socket.IO with flutter?如何在 Flutter 中使用 WebSockets 和 Socket.IO?
【发布时间】:2020-09-29 11:53:27
【问题描述】:

我一直在尝试将我的 Flutter 应用程序与使用套接字的节点 js 服务器集成,我将 WebSockets 用于 Flutter 部分,将 Socket.io 用于 nodejs 部分,并制作一个服务器以将其连接到 Flutter 客户端。

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 端口上创建了一个服务器,现在我想使用 Flutter 客户端与该服务器通信。

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

在这些之后,当我尝试发送消息并将其取回时,我无法做到。我真的认为这应该有效。如果不是应该怎么办?这里真的需要一些帮助。 谢谢!

【问题讨论】:

标签: node.js flutter dart websocket socket.io


【解决方案1】:

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

socket io 文档在第一页解释了为什么你不能这样做:https://socket.io/docs/

这是另一个解释差异的好帖子: https://www.hackdoor.io/articles/6xQkgQo4/differences-between-websockets-and-socketio

【讨论】:

  • 这里有什么替代品?
  • 你要么使用 websocket 要么使用 socket io。你必须选择一个。
  • 如果我选择 Socket.io 作为节点,哪个库用于颤振客户端?和 websocket 类似?
  • 或许可以看看这篇文章:medium.com/@andryy.ko/…
  • 我们不一定需要 node.js 来实现这个?
【解决方案2】:

我有 socket.io 服务器和 Flutter 应用程序

我建议使用 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 ');
    });
});

https://pub.dev/packages/socket_io_client/versions/0.9.12

这会在你的包的 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();
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2020-11-10
    • 2012-04-24
    • 2015-03-30
    • 2011-03-28
    • 2011-12-27
    • 2011-09-15
    相关资源
    最近更新 更多