2

Trying to follow https://flutter.dev/docs/cookbook/networking/web-sockets

a minimalistic flutter program, trying to send a message to my server:

import 'package:flutter/material.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void sendMessage(String message){

    final channel = WebSocketChannel.connect(
      Uri.parse('ws://192.1XX.XX.XX:5000'),);
    channel.sink.add(message);
    return;}


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Dor'),
            TextButton(onPressed: (){
              sendMessage('Message text should go here');
            }, child: Text('PressMe'))
          ],
        ),
      ),

    );
  }
}

However, this doesn't send anything to my server. No error message so it's challenging to debug... The server is working, because the following client code does send data to my server:

<html>
<head>
<title>Chat Room</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.2/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {

    var socket = io.connect('ws://192.XXX.XX.XX:5000');

    socket.on('connect', function() {
        socket.send('User has connected!');
    });

    socket.on('message', function(msg) {
        $("#messages").append('<li>'+msg+'</li>');
        console.log('Received message');
    });

    $('#sendbutton').on('click', function() {
        socket.send($('#myMessage').val());
        $('#myMessage').val('');
    });

});
</script>
<ul id="messages"></ul>
<input type="text" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>

but just in case you need it, here's my server's code:

from flask import Flask
from flask_socketio import SocketIO, send

app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecret'
socketio = SocketIO(app, cors_allowed_origins='*')

@app.route('/hello')
def say_hello():
    return 'HTTP is working!'


@socketio.on('message')
def handleMessage(msg):
    print('Message: ' + msg)
    send(msg, broadcast=True)

if __name__ == '__main__':
    socketio.run(app,host='0.0.0.0',port=5000)
yoni keren
  • 300
  • 2
  • 14

1 Answers1

2

Your server implements the Socket.IO protocol, which is not the same as WebSocket. Your flutter application should use a Socket.IO client if it intends to connect to a Socket.IO server.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Interesting! Looking at https://socket.io/ website :"In most cases, the connection will be established with WebSocket". Therefore I'm still confused, but it will be hilarious if it's actually a different protocol :D Also on flask_socketio's page here https://flask-socketio.readthedocs.io/en/latest/intro.html there's websocket mentioned a billion times. Huh. – yoni keren Oct 19 '21 at 23:30
  • 1
    Socket.IO uses WebSocket. That does not mean that they are the same. – Miguel Grinberg Oct 20 '21 at 08:14
  • True. Was misled by some tutorial (https://medium.com/swlh/implement-a-websocket-using-flask-and-socket-io-python-76afa5bbeae1). Since you are the author of flask_sockets, is it possible to do something better than a "while True" or "while not socket.closed" with the package as in here: https://pythonrepo.com/repo/heroku-python-flask-sockets-python-websocket (which would keep a process busy as the calls are blocking)? Can't find a reasonable example in the Oreilly books or repos documentations either for a multiple users chat using just websockets. – yoni keren Oct 20 '21 at 13:54
  • I'm not the author of flask-sockets. – Miguel Grinberg Oct 20 '21 at 22:28