0

I have a Flask_SocketIO app that supposed to implement a chat groups system. The client thats interacting with it is a flutter app. I wrote a test to see if the socketio events are working. it worked once, but than stopped. the server is getting the client's emits but not emitting back to the client. also, the connection related evets (connect, disconnect, error) seems to be fully working. the client's callbacks on these events are called.

My flutter test client:

void main() async {
  setupLocator();
  final api = locator<Api>();
  final socketService = locator<SocketService>();
  Message msg = Message(
      msgId: null,
      content: "Hello!",
      senderId: 1,
      senderName: 'tair',
      sendtime: DateTime.now().toString(),
      groupId: 1);

  runApp(
    MaterialApp(
      home: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
                child: Text("Disconnect"),
                onPressed: () {
                  socketService.leave(1, 1);
                }),
            RaisedButton(
              child: Text("Send"),
              onPressed: () {
                socketService.sendMessage(msg);
              },
            ),
            RaisedButton(
              child: Text("Connect"),
              onPressed: () {
                socketService.connect(1, 1, (data) {
                  print('Data!');
                  print(data);
                });
              },
            ),
          ],
        ),
      ),
    ),
  );
  SharedPreferences.setMockInitialValues({});

  await api.login('tair', '1234');
  await socketService.getToken();
  socketService.connect(1, 1, (data) {
    print('Data!');
    print(data);
  });
  • Api: A class that's interacting with rest api. not related
  • SocketService: A class that's emitting and listening to events. im giving the connect() method parameters in order to join a socketio room on the server side
  • locator: Dependency injecttion using pub package get_it. also not related

Here's the events on my Server:

@sock.on('join')
def join_group_room(data):
    print(data)
    token = data['token']
    if token in user_token.keys():
        group = Group.query.filter_by(id=int(data['groupId'])).first()
        if group.temp_participants is None:
            group.temp_participants = data['userId'] + ','
        else:
            group.temp_participants += data['userId'] + ','

        db.session.commit()
        join_room(data['groupId'])
        #print(rooms())
    else:
        emit('error', 'Invalid token')


@sock.on('message')
def message_room(data):
    print(data)
    token = data['token']
    if token in user_token.keys():
        message = Message(content=data['message'], groupid=int(data['groupId']), username=user_token[token],
                          datetime=data['datetime'])

        db.session.add(message)
        db.session.commit()

        participants = Group.query.filter_by(id=message.groupid).first().participants.split(",")
        temp_participants = Group.query.filter_by(id=message.groupid).first().temp_participants.split(",")

        for participant in participants:
            if participant not in temp_participants:
                pushbots.push_batch(platform=pushbots.PLATFORM_ANDROID,
                                              alias=participant,
                                              msg='A new message arrived', payload={'data': {'message': message.content,
                                                                                             'messageId': message.id,
                                                                                             'username': user_token[
                                                                                                 token],
                                                                                             'datetime': message.datetime,
                                                                                             'groupId': message.groupid,
                                                                                             'userId': User.query.filter_by(
                                                                                                 username=user_token[
                                                                                                    token]).first().id}})
        print("Emitting")
        emit('message', {'message': message.content, 'messageId': message.id,
                         'username': user_token[token], 'datetime': message.datetime,
                         'groupId': message.groupid,
                         'userId': User.query.filter_by(username=user_token[token]).first().id},
             room=message.groupid)
        sock.sleep(0)

    else:
        emit('error', 'Invalid token')


@sock.on('leave')
def leave_group_room(data):
    print(data)
    token = data['token']
    if token in user_token.keys():
        group = Group.query.filter_by(id=int(data['groupId'])).first()
        group.temp_participants = str(group.temp_participants.split(",").remove(data['userId'])).strip('[]')
        db.session.commit()

        leave_room(data['groupId'])
    emit('error', 'Invalid token')

Im using eventlet as async_mode for the socketio app. i looked up online for solutions and many people said i should add the following line to the main script:

import eventlet
eventlet.monkey_patch()

Also, according to my partner on this project, the events are working fine on his machine

for further explaination, here is the link to my git repo, so you can watch the whole code: My git repo (its on integration/ClientServer branch)

Thanks for helping!

DJ E.T
  • 31
  • 4
  • You should make an effort to simplify your code so that it has just what's enough to demonstrate and reproduce the problem. Just from glancing at your code I don't see anything obviously wrong, so this is very likely a small detail. – Miguel Grinberg Apr 19 '20 at 22:21
  • @Miguel Actually i did tried this, i made a smaller app with just 2 events: one that gets the client into a room and one that brodcasts a message in this room. I checked it with a python client and a dart client. The result was even stranger: the python client's messages sent successfully to the server and broadcasted to the 2 clients, but the dart client's messages only got to the server but not back to the clients. – DJ E.T Apr 22 '20 at 15:18
  • A client cannot emit directly to other clients, only to the server. Then the server can forward what it receives from one client to another. – Miguel Grinberg Apr 22 '20 at 15:32
  • @Miguel nevermind, I solved it. apparently roomnames are saved as string, but the emit function wont throw an error if you give an int as the room parameter. Thanks for your help! – DJ E.T Apr 22 '20 at 16:50

1 Answers1

0

Apperantly, room names can be only strings, but the emit function wont throw an error if youll pass an int as the room parameter.

DJ E.T
  • 31
  • 4