0

I'm trying to create a project and one of its functionalities is having a chat. The structure for chat is: App made in React Native and the backend i'm using Flask. For the backend i have many different routes and my intention is to create another route for handling user messages with WebSocket. I'm having many issues with flask_socketio. I tried a small version of websocket using NodeJs and it worked flawlessly. That's what i did so far:

RN app(frontend):
import SocketIOClient from 'socket.io-client'
import {GiftedChat} from 'react-native-gifted-chat'
export default class ChatScreen extends React.Component{
    static navigationOptions = ({ navigation }) => {
            return{
                title:`${navigation.getParam('mTitle')}`
            }
    }
    state={
        messages:[]
    }

    constructor(props){
      super(props)
      this.socket = SocketIOClient('http://a960eba8.ngrok.io');
      // this.socket.on('message', this.onReceivedMessage);
      this.socket.on("chat_message", msg => {
        console.log('mensagem recebida: ',msg)
        // this.setState({ chatMessages: [...this.state.chatMessages, msg] });
      });
    }
    componentDidMount() {
      console.log('component did mount function')
        this.setState({
          messages: [
            {
              _id: 1,
              text: 'Hello developer',
              createdAt: new Date(),
              user: {
                _id: 2,
                name: 'React Native',
                avatar: 'https://placeimg.com/140/140/any',
              },
            },
          ],
        })

      }
      onReceivedMessage = (message)=>{
        console.log('message received:',message)
      }
      onSend(messages = []) {
        this.setState(previousState => ({
          messages: GiftedChat.append(previousState.messages, messages),
        }))
        let msg = messages[0].text
        console.log('emit message: ',msg)
        this.socket.emit('chat_message',{message:msg})
        console.log('quite done')
      }

      render() {
        return (
            <GiftedChat
            messages={this.state.messages}
            onSend={messages => this.onSend(messages)}
            user={{
              _id: 1,
            }}
            />
        )
      }
}

Node backend that i tried for testing...

const express = require("express");
const app = express();
const server = require("http").createServer(app);
const io = require("socket.io").listen(server);
const port = 3000;
const ws_event = "chat_message"
console.log('novo cod...')
io.on("connection", socket => {
  console.log("a user connected :D");
  socket.on(ws_event, msg => {
    console.log(msg);
    io.emit(ws_event, msg);
  });
});

server.listen(port, () => console.log("server running on port:" + port));

Flask backend:

...
app = config_server() # flask app
db = app.db
m_test_room = 'm_room_123'
Session(app)
##----------------------------------------------------------------##
True,manage_session = True)
socketio = SocketIO(app,manage_session = False)

def estrutura_server():
    from src.util.util_outros import cria_pastas_necessarias
    cria_pastas_necessarias()
    pass

# api = create_api(app) # swagger
if __name__ == '__main__':
    estrutura_server()
    configure_websocket(socketio, app)
    if set_is_debug() is False:
        port = int(os.environ.get('PORT'))
        logging.debug('running on heroku, port: ', port)
        app.run(host='0.0.0.0', port=port)
    else:
        app.run(host='localhost', port = 3000, debug=True)

    # socketio.run(host="localhost", port=3000, debug=True, app=app)

Configure websocket function:

def configure_websocket(socketio_object,flask_app):
    from src.resources.reatime_resources.chatsocketresources import SocketChat
    socketio_object.on_namespace(SocketChat(''))

Namespace for handling websocket:

from  flask_socketio import Namespace, emit

class SocketChat(Namespace):


    def on_join(self,**kwargs):
        print('join interno: ',kwargs)


    def on_connect(self,**kwargs):
        print('on connect interno')
        emit('chat_message','chegou aqui no backend')
        pass

    def on_chat_message(self,**kwargs):
        print('on chat message::',kwargs)
        emit('chat_message',kwargs)

Maybe it's important to mention that i'm using ngrok for tunneling between the frontend(mobile app) and the backend. Error message on PyCharm(for flask backend):

INFO:engineio.server:96d6a2bae8c94cd98ed4003c3b9bf53e: Sending packet OPEN data {'sid': '96d6a2bae8c94cd98ed4003c3b9bf53e', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
INFO:socketio.server:emitting event "chat_message" to all [/]
INFO:engineio.server:48d735483b7f4cd5b0efb60c5f0493cf: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:96d6a2bae8c94cd98ed4003c3b9bf53e: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:96d6a2bae8c94cd98ed4003c3b9bf53e: Sending packet MESSAGE data 0
INFO:werkzeug:127.0.0.1 - - [09/Feb/2020 08:44:06] "GET /socket.io/?EIO=3&transport=polling&t=N0fmuTD HTTP/1.1" 200 -
on connect interno
WARNING:engineio.server:Invalid session None
INFO:werkzeug:127.0.0.1 - - [09/Feb/2020 08:44:07] "POST /socket.io/?EIO=3&transport=polling&t=N0fmud0 HTTP/1.1" 400 -
INFO:engineio.server:ebfeb359a601499a8df9db58415092ed: Sending packet OPEN data {'sid': 'ebfeb359a601499a8df9db58415092ed', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
INFO:socketio.server:emitting event "chat_message" to all [/]
INFO:engineio.server:48d735483b7f4cd5b0efb60c5f0493cf: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:96d6a2bae8c94cd98ed4003c3b9bf53e: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:ebfeb359a601499a8df9db58415092ed: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:ebfeb359a601499a8df9db58415092ed: Sending packet MESSAGE data 0
INFO:werkzeug:127.0.0.1 - - [09/Feb/2020 08:44:12] "GET /socket.io/?EIO=3&transport=polling&t=N0fmvrF HTTP/1.1" 200 -
on connect interno
WARNING:engineio.server:Invalid session None
INFO:werkzeug:127.0.0.1 - - [09/Feb/2020 08:44:13] "POST /socket.io/?EIO=3&transport=polling&t=N0fmv-y HTTP/1.1" 400 -
INFO:engineio.server:87e52ce8da464b6a86c979e8dd2fd1a3: Sending packet OPEN data {'sid': '87e52ce8da464b6a86c979e8dd2fd1a3', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
INFO:socketio.server:emitting event "chat_message" to all [/]
INFO:engineio.server:48d735483b7f4cd5b0efb60c5f0493cf: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:96d6a2bae8c94cd98ed4003c3b9bf53e: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:ebfeb359a601499a8df9db58415092ed: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:87e52ce8da464b6a86c979e8dd2fd1a3: Sending packet MESSAGE data 2["chat_message","chegou aqui no backend"]
INFO:engineio.server:87e52ce8da464b6a86c979e8dd2fd1a3: Sending packet MESSAGE data 0
INFO:werkzeug:127.0.0.1 - - [09/Feb/2020 08:44:18] "GET /socket.io/?EIO=3&transport=polling&t=N0fmxD8 HTTP/1.1" 200 -
on connect interno

Error message for React Native app on Android Studio:

W/unknown:ReactNative: failed to decode string from byte array
W/unknown:ReactNative: failed to decode string from byte array
W/unknown:ReactNative: failed to decode string from byte array

1 Answers1

2

The Invalid session None error that you are getting is common with the React Native frontend. See here, here and here for previous reports of this same issue.

The workaround that seems to work is to ask the React Native Socket.IO client to connect directly with WebSocket. The problem exists only when the client connects via HTTP and then upgrades to WebSocket. Here is an example connection that uses WebSocket directly:

SocketIOClient(`http://a960eba8.ngrok.io`, {transports: ['websocket']});
Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Thank you very much!!! It worked perfectly, i'm having this problem for days and you helped me a lot !!! I also had to downgrade the Socket.io-client on RN from 2.2.0 to 2.1.1, and also changed to run to socketio.run(host="localhost", port=3000, debug=True, app=app) instead of the previous way – Marcos Paulo Júnior Feb 10 '20 at 00:07