'Unable to send websocket data from flutter app to go server

I am trying to create a server-client architecture using flutter app client and go server. Currently I am trying to send text input from flutter app, to read and print it on the server side using Websockets.

I have successfully tested my flutter app to echo from https://www.websocket.org/echo. To connect to my local server,here is the relevant bit

For connecting to server

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

When onPressed,to send user entered data, sendMessage() is called;

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

I have read the https://godoc.org/github.com/gorilla/websocket docs and other blogs to understand mux, handlefunc and listenandserve functions, but I'm not able to send data.

Here is my Go server:

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))

}

Edit: Added Flutter Client code.

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



Solution 1:[1]

More detailed answer:


on linux you can get the IP address with:

hostname -I or ifconfig

(the one after "inet:")


and then in Flutter:

static String serverIP = "192.168.0.3"; // your IP instead of localhost
static String port = "8080";
final WebSocketChannel channel = IOWebSocketChannel.connect("ws://$serverIP:$port");

Huge thanks to OP and @Danny Tuppeny for the explanations as to why

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Antonin GAVREL