如何在 flutter 中使用 WebSockets 和 Socket.IO?

Him*_*jan 4 websocket node.js socket.io dart flutter

我一直在尝试使用套接字将我的 flutter 应用程序与 Node 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'));
Run Code Online (Sandbox Code Playgroud)

我在这里创建了一个 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Avi*_* Lo 8

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

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

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