【问题标题】:Unable to send websocket data from flutter app to go server无法将 websocket 数据从颤振应用程序发送到服务器
【发布时间】:2020-08-16 02:10:52
【问题描述】:

我正在尝试使用 Flutter 应用程序客户端和 Go 服务器创建服务器-客户端架构。 目前我正在尝试从 Flutter 应用程序发送文本输入,以使用 Websockets 在服务器端读取和打印它。

我已经成功测试了我的颤振应用程序以从 https://www.websocket.org/echo 回显。 要连接到我的本地服务器,这里是相关位

用于连接服务器

  final channel = IOWebSocketChannel.connect('ws://localhost:8080/test');

当onPressed发送用户输入的数据时,调用sendMessage();

void sendMessage(){
    if(myController.text.isNotEmpty){
      channel.sink.add(myController.text);
    }
  }

我已阅读 https://godoc.org/github.com/gorilla/websocket 文档和其他博客以了解 mux、handlefunc 和 listenandserve 函数,但我无法发送数据。

这是我的 Go 服务器:

package main

import (
    "fmt"
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
        ReadBufferSize: 1024,
    }

func connectionHandler(w http.ResponseWriter, r *http.Request){
    conn, err := upgrader.Upgrade(w,r,nil)
    if err != nil {
        log.Println(err)
        return
    }

    for{
            messageType, p, err := conn.NextReader()
            fmt.Println(p)
            fmt.Println(messageType)
            if err != nil {
                log.Println(err)
                return
            }
    }

}

func main(){

    mux := http.NewServeMux()
    fmt.Printf("Connecting to server \n")

    mux.HandleFunc("/test", connectionHandler)

    log.Fatal(http.ListenAndServe(":8080", mux))

}

编辑: 添加了 Flutter 客户端代码。

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:web_socket_channel/html.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/status.dart' as status;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Shopping',
      initialRoute: 'home',
      theme: ThemeData(
        primarySwatch: Colors.lightBlue,
      ),
      routes: <String, WidgetBuilder>{
        'home': (BuildContext context) => HomePage(title: "Home"),
        '/shoppingpage': (BuildContext context) => ShoppingCart(title: "Shopping Cart Page"),
      },

    );
  }
}

class HomePage extends StatelessWidget {
  HomePage({Key key, this.title}) : super(key:key);
  final String title;
  final channel = IOWebSocketChannel.connect('ws://localhost:8080/test');
  TextEditingController myController = TextEditingController();
  final GlobalKey<ScaffoldState> _scaffoldkey = new GlobalKey<ScaffoldState>();

  @override
  void dispose(){
    myController.dispose();
    channel.sink.close();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          FlatButton(
              onPressed: (){
                return (Navigator.of(context).pushNamed('/shoppingpage'));
              },
              child: Text('Start Game'),
              color: Colors.blue,
              splashColor: Colors.green,

          ),

          TextField(
            controller: myController,

          ),

          FloatingActionButton(
            onPressed: (){
              sendMessage();
              _scaffoldkey.currentState.showSnackBar(SnackBar(
                content: Text('Sent'),
              ));
            },
            child: Icon(Icons.send),
          ),

          StreamBuilder(
            stream: channel.stream,
            builder: (context, snapshot){
              return snapshot.hasData ? Text(snapshot.data.toString(),
              ) : CircularProgressIndicator();
            }
          ),
        ],
      ),
    );
  }

  void sendMessage(){
    if(myController.text.isNotEmpty){
      channel.sink.add(myController.text);
    }
  }

}



class ShoppingCart extends StatelessWidget {
  ShoppingCart({Key key, this.title}) : super(key: key);
  final String title;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: BackButton(onPressed: (){
          return Navigator.pop(context);
        }),
      ),
    );
  }
}

【问题讨论】:

  • 提供有关发送消息时发生的情况的更多详细信息; Go 代码中的处理程序是否被调用?处理程序是否记录任何错误?
  • 这是我服务器的全部代码,没有处理程序没有记录任何错误。但是我在处理程序代码中打印了语句,根据它,代码从未进入处理程序。
  • Go 程序将打印发送到端点 ws://localhost:8080/test 的消息。建议调试问题的第一步:在 Web 浏览器中转到 localhost:8080/test。您应该收到 400 条响应,其中包含有关错误 ws 握手的消息。如果您没有收到此消息,则服务器存在某种操作错误(服务器未运行是操作错误的一个示例)。如果确实收到消息,请在客户端应用程序中查找问题。
  • @CeriseLimón 在我的浏览器上检查了 localhost;8080/test 并收到了你提到的错误请求。我已经仔细检查了我的客户端代码,但仍然没有发现任何问题。所以用客户端代码更新了我的帖子。

标签: go flutter websocket


【解决方案1】:

如果您在 PC 上运行 Go 服务器,但在移动/模拟器上运行 Flutter 应用程序,那么 localhost 将不起作用(它将指向移动/模拟器,而不是 PC)。

您需要使用从手机解析到 PC 的 IP 地址/主机名,并确保 Go 服务器绑定到网络可访问的 IP(并且没有防火墙)。

【讨论】:

  • 感谢您,我将 Flutter 应用程序的 ip 更改为我的电脑的本地 ip(使用 ifconfig 找到)。此外,我必须将我的服务器 ip 从 localhost 更改为 0.0.0.0,以便所有本地 ip 都可以监听服务器。这个答案解释得很好[链接] (superuser.com/a/949522)
猜你喜欢
  • 1970-01-01
  • 2018-05-11
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 2020-06-14
  • 2013-08-21
  • 2023-04-06
相关资源
最近更新 更多